Index: llvm/trunk/lib/Target/Mips/MipsFastISel.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/MipsFastISel.cpp +++ llvm/trunk/lib/Target/Mips/MipsFastISel.cpp @@ -102,7 +102,6 @@ bool fastLowerCall(CallLoweringInfo &CLI) override; bool fastLowerIntrinsicCall(const IntrinsicInst *II) override; - bool TargetSupported; bool UnsupportedFPMode; // To allow fast-isel to proceed and just not handle // floating point but not reject doing fast-isel in other // situations @@ -212,10 +211,6 @@ TII(*Subtarget->getInstrInfo()), TLI(*Subtarget->getTargetLowering()) { MFI = funcInfo.MF->getInfo(); Context = &funcInfo.Fn->getContext(); - bool ISASupported = !Subtarget->hasMips32r6() && - !Subtarget->inMicroMipsMode() && Subtarget->hasMips32(); - TargetSupported = - ISASupported && TM.isPositionIndependent() && getABI().IsO32(); UnsupportedFPMode = Subtarget->isFP64bit() || Subtarget->useSoftFloat(); } @@ -291,9 +286,6 @@ } unsigned MipsFastISel::fastMaterializeAlloca(const AllocaInst *AI) { - if (!TargetSupported) - return 0; - assert(TLI.getValueType(DL, AI->getType(), true) == MVT::i32 && "Alloca should always return a pointer."); @@ -404,9 +396,6 @@ // Materialize a constant into a register, and return the register // number (or zero if we failed to handle it). unsigned MipsFastISel::fastMaterializeConstant(const Constant *C) { - if (!TargetSupported) - return 0; - EVT CEVT = TLI.getValueType(DL, C->getType(), true); // Only handle simple types. @@ -1444,9 +1433,6 @@ } bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) { - if (!TargetSupported) - return false; - CallingConv::ID CC = CLI.CallConv; bool IsTailCall = CLI.IsTailCall; bool IsVarArg = CLI.IsVarArg; @@ -1531,9 +1517,6 @@ } bool MipsFastISel::fastLowerIntrinsicCall(const IntrinsicInst *II) { - if (!TargetSupported) - return false; - switch (II->getIntrinsicID()) { default: return false; @@ -1980,8 +1963,6 @@ } bool MipsFastISel::fastSelectInstruction(const Instruction *I) { - if (!TargetSupported) - return false; switch (I->getOpcode()) { default: break; Index: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp @@ -458,9 +458,19 @@ FastISel * MipsTargetLowering::createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo) const { - if (!funcInfo.MF->getTarget().Options.EnableFastISel) - return TargetLowering::createFastISel(funcInfo, libInfo); - return Mips::createFastISel(funcInfo, libInfo); + const MipsTargetMachine &TM = + static_cast(funcInfo.MF->getTarget()); + + // We support only the standard encoding [MIPS32,MIPS32R5] ISAs. + bool UseFastISel = TM.Options.EnableFastISel && Subtarget.hasMips32() && + !Subtarget.hasMips32r6() && !Subtarget.inMips16Mode() && + !Subtarget.inMicroMipsMode(); + + // Disable if we don't generate PIC or the ABI isn't O32. + if (!TM.isPositionIndependent() || !TM.getABI().IsO32()) + UseFastISel = false; + + return UseFastISel ? Mips::createFastISel(funcInfo, libInfo) : nullptr; } EVT MipsTargetLowering::getSetCCResultType(const DataLayout &, LLVMContext &, Index: llvm/trunk/test/CodeGen/Mips/Fast-ISel/check-disabled-mcpus.ll =================================================================== --- llvm/trunk/test/CodeGen/Mips/Fast-ISel/check-disabled-mcpus.ll +++ llvm/trunk/test/CodeGen/Mips/Fast-ISel/check-disabled-mcpus.ll @@ -1,3 +1,4 @@ +; Targets where we should not enable FastISel. ; RUN: llc -march=mips -mcpu=mips2 -O0 -relocation-model=pic \ ; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s ; RUN: llc -march=mips -mcpu=mips3 -O0 -relocation-model=pic -target-abi n64 \ @@ -7,8 +8,16 @@ ; RUN: llc -march=mips -mcpu=mips32r6 -O0 -relocation-model=pic \ ; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s + +; RUN: llc -march=mips -mattr=mips16 -O0 -relocation-model=pic \ +; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s + ; RUN: llc -march=mips -mcpu=mips32r2 -mattr=+micromips -O0 -relocation-model=pic \ ; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s +; RUN: llc -march=mips -mcpu=mips32r3 -mattr=+micromips -O0 -relocation-model=pic \ +; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s +; RUN: llc -march=mips -mcpu=mips32r5 -mattr=+micromips -O0 -relocation-model=pic \ +; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s ; RUN: llc -march=mips -mcpu=mips64 -O0 -relocation-model=pic -target-abi n64 \ ; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s @@ -21,9 +30,26 @@ ; RUN: llc -march=mips -mcpu=mips32r6 -O0 -relocation-model=pic \ ; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s -; CHECK: FastISel missed terminator: ret i32 0 +; Valid targets for FastISel. +; RUN: llc -march=mips -mcpu=mips32r0 -O0 -relocation-model=pic \ +; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s -check-prefix=FISEL +; RUN: llc -march=mips -mcpu=mips32r2 -O0 -relocation-model=pic \ +; RUN: -fast-isel-verbose <%s 2>&1 | FileCheck %s -check-prefix=FISEL + +; The CHECK prefix is being used by those targets that do not support FastISel. +; By checking that we don't emit the "FastISel missed terminator..." message, +; we ensure that we do not generate code through FastISel. + +; CHECK-NOT: FastISel missed terminator: ret i64 0 + +; The above CHECK will only be valid as long as we *do* emit the missed +; terminator message for targets that support FastISel. If we add support +; for i64 return values in the future, then the following FISEL check-prefix +; will fail and we will have to come up with a new test. + +; FISEL: FastISel missed terminator: ret i64 0 -define i32 @foo() { +define i64 @foo() { entry: - ret i32 0 + ret i64 0 } Index: llvm/trunk/test/CodeGen/Mips/Fast-ISel/double-arg.ll =================================================================== --- llvm/trunk/test/CodeGen/Mips/Fast-ISel/double-arg.ll +++ llvm/trunk/test/CodeGen/Mips/Fast-ISel/double-arg.ll @@ -1,5 +1,5 @@ -; RUN: not llc -march=mipsel -mcpu=mips32r2 -fast-isel -mattr=+fp64 < %s \ -; RUN: -fast-isel-abort=3 +; RUN: not llc -march=mipsel -mcpu=mips32r2 -mattr=+fp64 \ +; RUN: -O0 -relocation-model=pic -fast-isel-abort=3 < %s ; Check that FastISel aborts when we have 64bit FPU registers. FastISel currently ; supports AFGR64 only, which uses paired 32 bit registers. Index: llvm/trunk/test/CodeGen/Mips/tailcall/tail-call-arguments-clobber.ll =================================================================== --- llvm/trunk/test/CodeGen/Mips/tailcall/tail-call-arguments-clobber.ll +++ llvm/trunk/test/CodeGen/Mips/tailcall/tail-call-arguments-clobber.ll @@ -21,6 +21,7 @@ declare i32 @func2(i32, i32, i32, i32, i32, i32) define i32 @func1(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f){ +; MIPS32-LABEL: func1: ; MIPS32: lw ${{[0-9]+}}, {{[0-9]+}}($sp) ; MIPS32-NEXT: lw ${{[0-9]+}}, {{[0-9]+}}($sp) @@ -40,6 +41,7 @@ define i64 @func3(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e, i64 %f, i64 %g, i64 %h, i64 %i, i64 %j){ +; MIPS64-LABEL: func3: ; MIPS64: ld ${{[0-9]+}}, {{[0-9]+}}($sp) ; MIPS64-NEXT: ld ${{[0-9]+}}, {{[0-9]+}}($sp) Index: llvm/trunk/test/DebugInfo/Mips/dsr-non-fixed-objects.ll =================================================================== --- llvm/trunk/test/DebugInfo/Mips/dsr-non-fixed-objects.ll +++ llvm/trunk/test/DebugInfo/Mips/dsr-non-fixed-objects.ll @@ -1,6 +1,6 @@ -; RUN: llc -march=mips -mcpu=mips32r2 -O0 -filetype=obj <%s | \ +; RUN: llc -march=mips -mcpu=mips32r2 -O0 -filetype=obj -fast-isel=0 <%s | \ ; RUN: llvm-dwarfdump -debug-dump=all - | FileCheck %s -check-prefix=F2 -; RUN: llc -march=mips -mcpu=mips32r2 -O0 -filetype=obj <%s | \ +; RUN: llc -march=mips -mcpu=mips32r2 -O0 -filetype=obj -fast-isel=0 <%s | \ ; RUN: llvm-dwarfdump -debug-dump=all - | FileCheck %s -check-prefix=F3 declare void @llvm.dbg.declare(metadata, metadata, metadata)