clangir
clangir copied to clipboard
CIR Record Layout diverges from LLVM's one
There are some differences between record layout in CIR and in LLVM IR.
Consider the next example.
typedef struct {
char a;
char b;
char c;
int d: 2;
int e: 2;
int f: 4;
int g: 25;
int h: 3;
int i: 4;
int j: 3;
int k: 8;
int l: 14;
} U;
CIR generates the next type:
!ty_22U22 = !cir.struct<struct "U" {!cir.int<s, 8>, !cir.int<s, 8>, !cir.int<s, 8>, !cir.int<u, 64>, !cir.int<u, 16>}>
Though the LLVM IR creates byte array for bit fields in this type:
%struct.U = type { i8, i8, i8, [9 x i8] }
Since CIR supports only fixed length integers (up to 64 bits now), we constraint the storage size up to it - that's why we have two
'fields' for bit fields in the result type.
Also, there are features that still not implemented in CIRRecordLayoutBuilder
(or somewhere in the LoweringPrepare
if it will be possible).
All this lead to the different data types emitted by CIR and LLVM IR.
Like in the example above, different underlying data type for bit fields lead to the different alignment computed - and hence (!) the struct is considered as the packed one, which is not true.
The exact way how to fix the problem is still an open question. Thus, we may implement all these functions but in the same time we'll bring some low details in CIR.
Several ideas
Speaking about the solution, the only I have in my mind is about padding - we can create an attribute for padding and do an actual padding somewhere in the lowering. But I would say padding is the least interesting problem right now.
Another idea is about these storage types - and we may try to create byte array for bit field storage when possible here in the first place, this may solve the problems caused by IntTyp
limitations.