================
@@ -11,8 +11,8 @@ typedef struct {
int c : 17;
} S;
-// CIR: !rec_S = !cir.struct<"S" {bitfield !u32i}>
-// LLVM: %struct.S = type { i32 }
+// CIR: !rec_S = !cir.struct<"S" {bitfield !u32i, bitfield
!cir.array<!cir.array<!u8i x 2> x 0>}>
----------------
adams381 wrote:
It is a bit awkward. Andy is also asking about a different representation, so
I have put an alternative in a top level comment.
What you are looking at on that line is a pair of members to describe the
bitfield.
```c
typedef struct {
int a : 4;
int b : 11;
int c : 17;
} S;
```
generates
```mlir
// CIR: !rec_S = !cir.struct<"S" {bitfield !u32i, bitfield
!cir.array<!cir.array<!u8i x 2> x 0>}>
```
`bitfield !u32i` is the real 4-byte access unit holding `a`, `b` and `c`. The
second member occupies no storage, and the byte count inside it is a payload
rather than a size. `c` is declared `int` at bit offset 15, so its declared
type ends at bit 47, two bytes past the unit's end.
This is the representation I landed on after `empty_bitfield` was dropped from
#216864 as a duplicate of `empty`. I couldn't get a single member to represent
everything a bitfield needs to represent so I went with the two member
approach. The two array levels in the second member do different jobs. The
outer zero length signals that the member occupies no storage, so the layout
walks skip it. The inner byte array only exists to carry the number "2". It
is a byte array rather than a named type because a unit can hold bit-fields of
several different declared types, so there is no single one to name. So, the
whole thing is read as, "This is a bitfield in a compiler selected storage of
size `!u32i`, but its declared type extends 2 bytes past that."
https://github.com/llvm/llvm-project/pull/220069
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits