Haishan
2013-Nov-28 13:45 UTC
[LLVMdev] Question about ExprConstant optimization of IR stage
hi, I compile a case (test.c) to get IR file (test.ll) using clang as follows: "clang -emit-llvm -S -O2 test.c -o test.ll" My clang source code version is release 3.3 and debugging build. //test.c int foo(int j) { return ++j > 0; } int main() { if (foo(((~0U)>>1))) abort(); exit(0) } //end test.c Here are the generated IR file: //test.ll ; Function Attrs: noreturn nounwind uwtable define i32 @main #1 { if.then: tail call void @abort() #3 unreachable } //end test.ll As we can see from test.ll, foo function is optimized out by clang. And then call abort function directly. However, the real is that this test never executes abort function. So, I debug source code of clang. In the 3167 line of ExprConstant.cpp(tools/clang/lib/AST/ExprConstant.cpp), these codes are 3166: // Don't call function pointers which have been cast to some other type. 3167: if (!Info.Ctx.hasSameType(CalleeType->getPointeeType(), FD->getType())) 3168: return Error(E); It returns Error(E) . Then, the expression "foo(((~0U)>>1))" is optimized out in the later stage. Here FD is foo's function pointer, so I think it should not return Error. Maybe it is bug, could someone help me with that? Thanks a million in advance. --Haishan -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20131128/271832ba/attachment.html>
Tim Northover
2013-Nov-28 14:02 UTC
[LLVMdev] Question about ExprConstant optimization of IR stage
Hi Haishan,> int foo(int j) { > return ++j > 0; > } > int main() { > if (foo(((~0U)>>1))) > abort(); > exit(0) > }This test contains undefined behaviour, and you can never rely on the compiler doing anything predictable with that. Specifically, the result of casting (~0U) >> 1 to an int is almost certainly INT_MAX and when foo increments it integer overflow occurs, which is undefined. Cheers. Tim.
Haishan
2013-Nov-29 13:26 UTC
[LLVMdev] Question about ExprConstant optimization of IR stage
Hi Tim, Firstly, thanks for your reply. I agree on your idea about integer overflow in this test. But, in fact, the content of this test is the same to gcc\testsuite\gcc.c-torture\execute\920612-1.c. gcc can handle it correctly. Moreover, when I compile this test using clang with optlevel O0 instead of O2. Its execution result is the same to gcc. That to say, for this test, clang with optlevel O2 execution result is different from O0. Is it reasonable? Thanks a lot. -Haishan At 2013-11-28 22:02:51,"Tim Northover" <t.p.northover at gmail.com> wrote:>Hi Haishan, > >> int foo(int j) { >> return ++j > 0; >> } >> int main() { >> if (foo(((~0U)>>1))) >> abort(); >> exit(0) >> } > >This test contains undefined behaviour, and you can never rely on the >compiler doing anything predictable with that. Specifically, the >result of casting (~0U) >> 1 to an int is almost certainly INT_MAX and >when foo increments it integer overflow occurs, which is undefined. > >Cheers. > >Tim.-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20131129/8b5cd85f/attachment.html>