Index: lib/Target/Mips/MipsFastISel.cpp =================================================================== --- lib/Target/Mips/MipsFastISel.cpp +++ 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,11 +211,7 @@ 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(); + UnsupportedFPMode = Subtarget->isFP64bit() || Subtarget->useSoftFloat(); } unsigned fastMaterializeAlloca(const AllocaInst *AI) override; @@ -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. @@ -1440,9 +1429,6 @@ } bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) { - if (!TargetSupported) - return false; - CallingConv::ID CC = CLI.CallConv; bool IsTailCall = CLI.IsTailCall; bool IsVarArg = CLI.IsVarArg; @@ -1527,9 +1513,6 @@ } bool MipsFastISel::fastLowerIntrinsicCall(const IntrinsicInst *II) { - if (!TargetSupported) - return false; - switch (II->getIntrinsicID()) { default: return false; @@ -1976,8 +1959,6 @@ } bool MipsFastISel::fastSelectInstruction(const Instruction *I) { - if (!TargetSupported) - return false; switch (I->getOpcode()) { default: break; Index: lib/Target/Mips/MipsISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsISelLowering.cpp +++ lib/Target/Mips/MipsISelLowering.cpp @@ -458,9 +458,21 @@ 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()); + + // FastISel is supported only for [MIPS32,MIPS32R6) ISAs. + bool UseFastISel = TM.Options.EnableFastISel && Subtarget.hasMips32(); + + // Disable FastISel if we use MIPS32R6 or any microMIPS mode. + if (Subtarget.hasMips32r6() || Subtarget.inMicroMipsMode()) + UseFastISel = false; + + // 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: test/CodeGen/Mips/Fast-ISel/check-disabled-mcpus.ll =================================================================== --- test/CodeGen/Mips/Fast-ISel/check-disabled-mcpus.ll +++ 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,13 @@ ; RUN: llc -march=mips -mcpu=mips32r6 -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 +27,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: test/CodeGen/Mips/Fast-ISel/double-arg.ll =================================================================== --- test/CodeGen/Mips/Fast-ISel/double-arg.ll +++ 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: test/CodeGen/Mips/tailcall/tail-call-arguments-clobber.ll =================================================================== --- test/CodeGen/Mips/tailcall/tail-call-arguments-clobber.ll +++ 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: test/DebugInfo/Mips/dsr-non-fixed-objects.ll =================================================================== --- test/DebugInfo/Mips/dsr-non-fixed-objects.ll +++ 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)