Christophe de Dinechin
2010-Feb-27 11:17 UTC
[LLVMdev] Object layout bug for C++ derived class with long long integer
I have a simple C++ class that looks like this: struct Foo { Thing *first; Blob *second; unsigned long third; }; Then I have a derived C++ class that look like this: struct Bar : Foo { long long fourth; } I generate JIT code to access 'fourth' from a Foo * as follows: BarPtr = CreateBitCast(FooPtr, BarPtrTy); FourthPtr = CreateConstGEP2_32(BarPtr, 0, 3); FourthValue = CreateLoad(FourthPtr); ConstantValue = ConstantInt::get(FourthValue->getType(), 0x2A4); ComparisonValue = CreateICmpEQ(FourthValue, ConstantValue); This appears to work on Linux and MacOSX with LLVM 2.6 and LLVM 2.7. On Windows, however, where I only have LLVM 2.6 with MINGW/MSYS, the generated code looks like this: 0x13df70b3: mov $0x2a4,%ecx 0x13df70b8: xor 0xc(%edi),%ecx 0x13df70bb: or 0x10(%edi),%ecx 0x13df70be: test %ecx,%ecx 0x13df70c0: jne 0x13df70ec This is wrong compared to the native layout of the C++ object. What the generated code does is compare against values at ecx+12..19, but the C++ object has 'fourth' at ecx+16..23. The compiler inserts some padding in Foo between third (32-bit) and fourth (64-bit), presumably for alignment reasons. My question is why LLVM doesn't do the same thing. I'm not sure if this is a layout bug in LLVM, if I need some magic incantation to tell LLVM to align 'fourth' to its natural boundary, or if my LLVM declaration of 'Bar' is incorrect. Any suggestion as to the correct resolution would be appreciated. Thanks Christophe
Anton Korobeynikov
2010-Feb-27 12:33 UTC
[LLVMdev] Object layout bug for C++ derived class with long long integer
Hello, Christophe> I have a simple C++ class that looks like this: > > struct Foo { Thing *first; Blob *second; unsigned long third; }; > > Then I have a derived C++ class that look like this: > > struct Bar : Foo { long long fourth; }How does the generated LLVM IR for these structs look like?> This is wrong compared to the native layout of the C++ object.What is the "native layout of the C++ object"? How is it defined?> The compiler inserts some padding in Foo between third (32-bit) and fourth (64-bit), presumably for alignment reasons.Which compiler? llvm-gcc tries to follow the mainline gcc for mingw platform. There were some changes post-2.6 wrt long long native alignment, you might try to look into code at svn head. -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University
Anton Korobeynikov
2010-Feb-27 14:35 UTC
[LLVMdev] Object layout bug for C++ derived class with long long integer
>> How does the generated LLVM IR for these structs look like? > > For Foo:I mean what was the IR generated by llvm-gcc for such code.>> llvm-gcc tries to follow the mainline gcc for mingw >> platform. There were some changes post-2.6 wrt long long native >> alignment, you might try to look into code at svn head. > > Unfortunately, svn head is incompatible with 2.6 (see an earlier email I sent on the list). Since 2.6 is what people get today from tools like apt-get or MacPorts, 2.7 is not really an option for me yet.Then you should workaround this bug somehow, sorry. -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University
Christophe de Dinechin
2010-Feb-27 14:44 UTC
[LLVMdev] Object layout bug for C++ derived class with long long integer
On 27 févr. 2010, at 15:35, Anton Korobeynikov wrote:> Then you should workaround this bug somehow, sorry.That's what I did for now by replacing the ulong with ulonglong. Thanks again. Christophe
Apparently Analagous Threads
- [LLVMdev] Object layout bug for C++ derived class with long long integer
- [LLVMdev] Changes in FunctionPassManager constructor
- [LLVMdev] Changes in FunctionPassManager constructor
- [LLVMdev] Changes in FunctionPassManager constructor
- [LLVMdev] Changes in FunctionPassManager constructor