Evan Jones
2005-Nov-01 23:56 UTC
[LLVMdev] Illegal Optimization(?): Combining empty type instances
I think I may have found an illegal optimization in LLVM. The problem is that if you have an empty type LLVM optimizes it away so it produces weird results. The assembler output from llvm-gcc clearly outputs the "alloca" instructions, so some other pass is removing them. I doubt if any real program relies on this behaviour, and there is a trivial work around. However, my program ran across this problem, so maybe it should be corrected. Example program: #include <stdio.h> struct Empty {}; struct Empty globalA; struct Empty globalB; int main( int argc, char* argv[] ) { struct Empty a; struct Empty b; printf( "%p %p\n", &a, &b ); printf( "%p %p\n", &globalA, &globalB ); return 0; } The expected output is that all four pointers will be unique and valid. With LLVM the output is: (nil) (nil) 0x4133aff9 0x4133aff9 Assembling and executing llvm-gcc's output directly is slightly better but the globals are still wrong: 0xbfffe0ef 0xbfffe0ee 0x4133aff9 0x4133aff9 Running llvm-gcc's output directly using 'lli -force-interpreter' is correct: 0x86b8748 0x86b8758 0x86a4058 0x86b8658 This caused a problem in my program because I was testing if the two addresses were equal, and the test was always returning true. The workaround is to put something in the structure so that LLVM doesn't optimize it away. The question is what does the C standard require? I'm assuming that GCC is doing the right thing, but I could be wrong. Evan Jones -- Evan Jones http://evanjones.ca/
Chris Lattner
2005-Nov-02 00:01 UTC
[LLVMdev] Illegal Optimization(?): Combining empty type instances
On Tue, 1 Nov 2005, Evan Jones wrote:> I think I may have found an illegal optimization in LLVM. The problem is that > if you have an empty type LLVM optimizes it away so it produces weird > results. The assembler output from llvm-gcc clearly outputs the "alloca" > instructions, so some other pass is removing them. I doubt if any real > program relies on this behaviour, and there is a trivial work around. > However, my program ran across this problem, so maybe it should be corrected. > > The expected output is that all four pointers will be unique and valid. WithUniqueness is something guaranteed by C++, but not by C. In C, empty structures have size = 0, which gives you funny cases like this. Consider the following: struct Empty {}; struct Empty Foo[10]; The size of both 'Empty' and 'Foo' are zero, which means that each element of Foo is at the same address. In the C++ world, this sort of thing is explicitly banned: the smallest structure you can get with standard C++ is one byte.> This caused a problem in my program because I was testing if the two > addresses were equal, and the test was always returning true. The workaround > is to put something in the structure so that LLVM doesn't optimize it away. > The question is what does the C standard require?I believe that LLVM's behavior is correct in this case.> I'm assuming that GCC is doing the right thing, but I could be wrong.GCC may well be doing what you expect in this case, but that may just be a side effect of it not optimizing as aggressively. -Chris -- http://nondot.org/sabre/ http://llvm.org/
Evan Jones
2005-Nov-02 00:40 UTC
[LLVMdev] Illegal Optimization(?): Combining empty type instances
On Nov 1, 2005, at 19:01, Chris Lattner wrote:> Uniqueness is something guaranteed by C++, but not by C.Ah! I knew that someone out there would have memorized the standards on this list, and llvm-g++ does the right thing. Never mind!> GCC may well be doing what you expect in this case, but that may just > be a side effect of it not optimizing as aggressively.That must be it. Evan Jones -- Evan Jones http://evanjones.ca/
Apparently Analagous Threads
- [LLVMdev] Illegal Optimization(?): Combining empty type instances
- [LLVMdev] Thread support: desirable or not?
- [LLVMdev] Thread support: desirable or not?
- [LLVMdev] llvm-ranlib: Bus Error in regressions + fix
- [LLVMdev] llvm-ranlib: Bus Error in regressions + fix