How are bitfields handled in StructLayout? In LLVM 2.5 the struct is unambiguously size by: StructSize += TD.getTypePaddedSize(Ty); // Consume space for this data In LLVM 2.6 it's getTypeAllocSize, which does the same thing. Unfortunately, this is not correct for bitfields. For example, LLVM reports this struct: typedef struct test1 { short f0 : 10; char f1 : 5; long f2 : 1; long f3 : 45; } test1_t; which in LLVM is: %test1 = type { i10, i5, i1, i45 } to have size 12 on x86-64 whien it should have size 8. I don't know how to work around this since the original bitfield type has been lost by the time we translate to LLVM. Does this need to be handled in the frontend, to munge the struct type and add the necessary masking and shifting so it works correctly? What does llvm-gcc do with something like this? -Dave
On Sep 22, 2009, at 1:27 PM, David Greene wrote:> How are bitfields handled in StructLayout? In LLVM 2.5 the > struct is unambiguously size by: > > StructSize += TD.getTypePaddedSize(Ty); // Consume space for this > data > > In LLVM 2.6 it's getTypeAllocSize, which does the same thing. > > Unfortunately, this is not correct for bitfields. For example, > LLVM reports this struct: > > typedef struct test1 { > short f0 : 10; > char f1 : 5; > long f2 : 1; > long f3 : 45; > } test1_t; > > which in LLVM is: > > %test1 = type { i10, i5, i1, i45 } > > to have size 12 on x86-64 whien it should have size 8.Fields like "i10" are not bitfields in the C sense. they get individually padded out to the nearest byte, not packed together densely. The C frontend is expected to lower the struct type as appropriate. For example, clang lowers that type to: %struct.test1 = type { [2 x i8], [6 x i8] }> Does this need to be handled in the frontend, to munge the struct type > and add the necessary masking and shifting so it works correctly?Yep, -Chris
I have a question. If the size of long is 8 on your x64 platform. Because the size of long is so different on different platform, sad it is. 2009/9/23, David Greene <dag at cray.com>:> How are bitfields handled in StructLayout? In LLVM 2.5 the > struct is unambiguously size by: > > StructSize += TD.getTypePaddedSize(Ty); // Consume space for this data > > In LLVM 2.6 it's getTypeAllocSize, which does the same thing. > > Unfortunately, this is not correct for bitfields. For example, > LLVM reports this struct: > > typedef struct test1 { > short f0 : 10; > char f1 : 5; > long f2 : 1; > long f3 : 45; > } test1_t; > > which in LLVM is: > > %test1 = type { i10, i5, i1, i45 } > > to have size 12 on x86-64 whien it should have size 8. > > I don't know how to work around this since the original bitfield type has > been > lost by the time we translate to LLVM. > > Does this need to be handled in the frontend, to munge the struct type > and add the necessary masking and shifting so it works correctly? > > What does llvm-gcc do with something like this? > > -Dave > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >-- 从我的移动设备发送 此致 礼 罗勇刚 Yours sincerely, Yonggang Luo
On Tuesday 22 September 2009 20:47, 罗勇刚 wrote:> I have a question. If the size of long is 8 on your x64 platform.Yes, it has to be to conform with the ABI.> Because the size of long is so different on different platform, sad it > is.Again, this is an ABI issue, as is bitfield layout. I think what's happening is that we're generating all the correct bitfield access code (our optimizer takes care of that). But our translator produces the wrong LLVM type which means arrays-of-structures don't work right in the presence of bitfields. We got away with it for a while until LLVM 2.5 got smarter and recognized more opportunities for strength reduction. Darn you LLVM people! I'll add it to my presentation at the dev meeting of suggested improvements to LLVM: our community should get a little dumber. :) -Dave