================
@@ -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

Reply via email to