[LLVMdev] strlen in fast-isel is missed

Reed Kotler rkotler at mips.com
Wed Jan 28 12:54:42 PST 2015


-fno-builtin

will also make this problem go away.


On 01/28/2015 12:33 PM, Reed Kotler wrote:
> Seems like it might possible to override TargetLIbraryInfo during the
> creation of the fast-isel object.
>
> I will look into this.
>
> namespace llvm {
> FastISel *Mips::createFastISel(FunctionLoweringInfo &funcInfo,
>                                 const TargetLibraryInfo *libInfo) {
>    return new MipsFastISel(funcInfo, libInfo);
> }
> }
>
>
> On 01/28/2015 11:03 AM, Reed Kotler wrote:
>> 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