Index: include/llvm/CodeGen/FastISel.h =================================================================== --- include/llvm/CodeGen/FastISel.h +++ include/llvm/CodeGen/FastISel.h @@ -199,6 +199,8 @@ const TargetLibraryInfo *LibInfo; bool SkipTargetIndependentISel; + bool HandleOptimizedCodeGenFunctions; + /// \brief The position of the last instruction for materializing constants /// for use in the current block. It resets to EmitStartPt when it makes sense /// (for example, it's usually profitable to avoid function calls between the @@ -535,6 +537,9 @@ bool selectExtractValue(const User *I); bool selectInsertValue(const User *I); + void setHandleOptimizedCodeGenFunctions(bool Value); + bool handleOptimizedCodeGenFunctions(); + private: /// \brief Handle PHI nodes in successor blocks. /// Index: lib/CodeGen/SelectionDAG/FastISel.cpp =================================================================== --- lib/CodeGen/SelectionDAG/FastISel.cpp +++ lib/CodeGen/SelectionDAG/FastISel.cpp @@ -1311,7 +1311,8 @@ // As a special case, don't handle calls to builtin library functions that // may be translated directly to target instructions. - if (F && !F->hasLocalLinkage() && F->hasName() && + if (!handleOptimizedCodeGenFunctions() && + F && !F->hasLocalLinkage() && F->hasName() && LibInfo->getLibFunc(F->getName(), Func) && LibInfo->hasOptimizedCodeGen(Func)) return false; @@ -1584,7 +1585,8 @@ TII(*MF->getSubtarget().getInstrInfo()), TLI(*MF->getSubtarget().getTargetLowering()), TRI(*MF->getSubtarget().getRegisterInfo()), LibInfo(LibInfo), - SkipTargetIndependentISel(SkipTargetIndependentISel) {} + SkipTargetIndependentISel(SkipTargetIndependentISel), + HandleOptimizedCodeGenFunctions(false) {} FastISel::~FastISel() {} @@ -2185,3 +2187,11 @@ return Predicate; } + +void FastISel::setHandleOptimizedCodeGenFunctions(bool Value) { + HandleOptimizedCodeGenFunctions = Value; +} + +bool FastISel::handleOptimizedCodeGenFunctions() { + return HandleOptimizedCodeGenFunctions; +} Index: lib/Target/Mips/MipsFastISel.cpp =================================================================== --- lib/Target/Mips/MipsFastISel.cpp +++ lib/Target/Mips/MipsFastISel.cpp @@ -167,6 +167,7 @@ ((Subtarget->hasMips32r2() || Subtarget->hasMips32()) && (static_cast(TM).getABI().IsO32()))); UnsupportedFPMode = Subtarget->isFP64bit(); + setHandleOptimizedCodeGenFunctions(true); } unsigned fastMaterializeConstant(const Constant *C) override; Index: test/CodeGen/Mips/Fast-ISel/strlen2.ll =================================================================== --- /dev/null +++ test/CodeGen/Mips/Fast-ISel/strlen2.ll @@ -0,0 +1,21 @@ +; RUN: llc -march=mipsel -relocation-model=pic -O0 -fast-isel -mips-fast-isel -fast-isel-abort -mcpu=mips32r2 \ +; RUN: < %s | FileCheck %s + +@.str = private unnamed_addr constant [6 x i8] c"hello\00", align 1 +@hello = global i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0), align 4 +@len = common global i32 0, align 4 + +; Function Attrs: nounwind +define void @foo() { +entry: +; CHECK: .ent foo + %0 = load i8** @hello, align 4 + %call = call i32 @strlen(i8* %0) #2 + store i32 %call, i32* @len, align 4 + ret void +} + +; Function Attrs: nounwind readonly +declare i32 @strlen(i8*) + +