[LLVMdev] strlen in fast-isel is missed

Reed Kotler rkotler at mips.com
Wed Jan 28 11:03:29 PST 2015


This issue occurs in a many library functions.
strlen, strcmp, ... many others.
I'm surprised nobody has noticed this because many basic blocks will 
fail to be compiled as fast-isel in this case.

It seems like just a bug in:
bool FastISel::selectInstruction(const Instruction *I) {

this function returns false but then it causes fast-isel to just do a 
miss on the function. there is no way to override the behavior.

Since this is happening on a call instructtion, it's going to drop back 
and print as a missed fast isel call.

It seems like this test in
bool FastISel::selectInstruction(const Instruction *I)

should just be deleted.

Thoughts?


     // 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() &&
         LibInfo->getLibFunc(F->getName(), Func) &&
         LibInfo->hasOptimizedCodeGen(Func))
       return false;


This is called from void SelectionDAGISel::SelectAllBasicBlocks(const 
Function &Fn)

     if (FastIS->selectInstruction(Inst)) {
           --NumFastIselRemaining;
           ++NumFastIselSuccess;
           // If fast isel succeeded, skip over all the folded 
instructions, and
           // then see if there is a load right before the selected 
instructions.
           // Try to fold the load if so.
           const Instruction *BeforeInst = Inst;
           while (BeforeInst != Begin) {
             BeforeInst = std::prev(BasicBlock::const_iterator(BeforeInst));
             if (!isFoldedOrDeadInstruction(BeforeInst, FuncInfo))
               break;
           }
           if (BeforeInst != Inst && isa<LoadInst>(BeforeInst) &&
               BeforeInst->hasOneUse() &&
               FastIS->tryToFoldLoad(cast<LoadInst>(BeforeInst), Inst)) {
             // If we succeeded, don't re-select the load.
             BI = std::next(BasicBlock::const_iterator(BeforeInst));
             --NumFastIselRemaining;
             ++NumFastIselSuccess;
           }
           continue;
         }

#ifndef NDEBUG
         if (EnableFastISelVerbose2)
           collectFailStats(Inst);
#endif

         // Then handle certain instructions as single-LLVM-Instruction 
blocks.
         if (isa<CallInst>(Inst)) {

           if (EnableFastISelVerbose || EnableFastISelAbort) {
             dbgs() << "FastISel missed call: ";
             Inst->dump();



On 01/20/2015 02:35 PM, reed kotler wrote:
> It seems that fast-isel for intel does not handle strlen. It's a general
> problem in fast-isel .
>
>
> ~/llvmw/build/Deb~/llvmw/build/Debug+Asserts/bin/clang -O0  -mllvm
> -fast-isel-verbose -mllvm -fast-isel strlen1.c
> strlen1.c:12:3: warning: implicitly declaring library function 'printf'
> with
>        type 'int (const char *, ...)'
>    printf("%i\n", len);
>    ^
> strlen1.c:12:3: note: include the header <stdio.h> or explicitly provide a
>        declaration for 'printf'
> FastISel missed call:   %call = call i64 @strlen(i8* %0) #3
> 1 warning generated.
>
> #include <string.h>
>
> char *hello = "hello";
> int len;
>
> void foo() {
>    len = strlen(hello);
> }
>
> int main() {
>    foo();
>    printf("%i\n", len);
> }




More information about the llvm-dev mailing list