Chuck Zhao
2010-Sep-30 00:21 UTC
[LLVMdev] strange code behavior when non-prototyped user function are called
I noticed a strange behavior when a non-prototyped user-defined function is called. E.g. for the following test.c code segment: void foo(void); void bar(void); void foo(void){ bar(); } void bar(void){ printf("inside bar()"); } LLVM-GCC 2.7 -O0 will generate the following code for foo(), which is all fine. define void @foo() nounwind { entry: * call void @bar() nounwind* br label %return return: ; preds = %entry ret void } However, if I comment out the first 2 lines (the prototype declarations), llvm-gcc will generate the following code for foo() instead: define void @foo() nounwind { entry: %0 = call i32 (...)* bitcast (void ()* @bar to i32 (...)*)() nounwind ; <i32> [#uses=0] br label %return return: ; preds = %entry ret void } Notice there is now a bitcast operator embedded inside the call instruction. The problem, however, is that the 2nd flavor of LLVM IR breaks my code, which tries to detect all Call Instructions inside all Functions: ... if (BitCastInst *BCI = dyn_cast<BitCastInst>(II)){ errs() <<"find BitCastInst\n"; ... } if (CallInst *CI = dyn_cast<CallInst>(II)){ errs() <<"find CallInst\n"; ... } ... As a result, neither of the above two cases can trigger. I am asking how I can detect all such function calls as CallInsts. Thank you very much Chuck -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20100929/837022d0/attachment.html>
Duncan Sands
2010-Sep-30 09:08 UTC
[LLVMdev] strange code behavior when non-prototyped user function are called
Hi Chuck,> However, if I comment out the first 2 lines (the prototype declarations), > llvm-gcc will generate the following code for foo() instead: > define void @foo() nounwind { > entry: > %0 = call i32 (...)* bitcast (void ()* @bar to i32 (...)*)() nounwind ; <i32> > [#uses=0]in C a prototype like this void bar() or no prototype at all means that bar takes a variable number of arguments (corresponds to ... in the LLVM type); if there is no prototype then bar is also considered to return i32. So in foo, the call to bar is technically a call to a function of type i32 (...). However later the body of bar is output, at which point the type of @bar is corrected to void (void). This results in a bitcast in the call. The instcombine pass should clean this up. Ciao, Duncan.
Chuck Zhao
2010-Sep-30 14:35 UTC
[LLVMdev] strange code behavior when non-prototyped user function are called
Duncan, Thank you for the reply. I fully agree with your explanation on how LLVM-GCC deals with user-defined function calls when their respective prototypes are not specified. I guess it is an internal hack on LLVM-IR when such cases happen, and -instcombine will naturally clean them up. I think a better option is just use -O2 (or -std-compile-opts), which includes -instcombine as part of its defaults. As how -instcombine does its work, I will have to read its source code. It is currently a task on my todo list for the weekend. :-) Thank you Chuck On 9/30/2010 5:08 AM, Duncan Sands wrote:> Hi Chuck, > >> However, if I comment out the first 2 lines (the prototype declarations), >> llvm-gcc will generate the following code for foo() instead: >> define void @foo() nounwind { >> entry: >> %0 = call i32 (...)* bitcast (void ()* @bar to i32 (...)*)() nounwind ;<i32> >> [#uses=0] > in C a prototype like this > void bar() > or no prototype at all means that bar takes a variable number of arguments > (corresponds to ... in the LLVM type); if there is no prototype then bar > is also considered to return i32. > > So in foo, the call to bar is technically a call to a function of type i32 > (...). However later the body of bar is output, at which point the type of > @bar is corrected to void (void). This results in a bitcast in the call. > The instcombine pass should clean this up. > > Ciao, > > Duncan. > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reasonably Related Threads
- [LLVMdev] strange code behavior when non-prototyped user function are called
- InstCombine GEP
- [LLVMdev] problem with replacing an instruction
- [LLVMdev] Assertion `InReg && "Value not in map!"' failed
- [LLVMdev] Assertion `InReg && "Value not in map!"' failed