StructLayout

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

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.

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. :slight_smile:

                             -Dave