================
@@ -0,0 +1,224 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o 
%t.cir
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o 
%t-cir.ll
+// RUN: FileCheck --check-prefix=LLVM,LLVMCIR --input-file=%t-cir.ll %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll 
+// RUN: FileCheck --check-prefix=LLVM,OGCG --input-file=%t.ll %s
+
+union JustBIUnion {
+  _BitInt(65) bi;
+};
+// CIR-DAG: !rec_JustBIUnion = !cir.union<"JustBIUnion" {data !cir.int<s, 65, 
bitint>}>
+// LLVM-DAG: %union.JustBIUnion = type { i128 }
+
+struct SmallerUnionMem { long long a; int b; };
+// CIR-DAG: !rec_SmallerUnionMem = !cir.struct<"SmallerUnionMem" {data !s64i, 
data !s32i}>
+// LLVM-DAG: %struct.SmallerUnionMem = type { i64, i32 }
+
+union BIUnion {
+  _BitInt(65) bi;
+  struct SmallerUnionMem m;
+};
+// CIR-DAG: !rec_BIUnion = !cir.union<"BIUnion" {data !cir.int<s, 65, bitint>, 
data !rec_SmallerUnionMem}>
+// LLVM-DAG: %union.BIUnion = type { i128 }
+
+union BIUnionArr {
+  _BitInt(65) bi;
+  char arr[20];
+};
+// CIR-DAG: !rec_BIUnionArr = !cir.union<"BIUnionArr" packed {data !cir.int<s, 
65, bitint>, data !cir.array<!s8i x 20>}, padding = {!cir.array<!u8i x 8>}>
+// LLVM-DAG: %union.BIUnionArr = type <{ i128, [8 x i8] }>
+
+struct First65 {
+  _BitInt(65) bi;
+  int i;
+};
+// CIR-DAG: !rec_First65 = !cir.struct<"First65" packed {data !cir.int<s, 65, 
bitint>, data !s32i, pad !cir.array<!u8i x 4>}>
+// LLVM-DAG: %struct.First65 = type <{ i128, i32, [4 x i8] }>
+
+struct Middle65 {
+  char c;
+  _BitInt(65) bi;
+  int i;
+};
+// CIR-DAG: !rec_Middle65 = !cir.struct<"Middle65" packed {data !s8i, pad 
!cir.array<!u8i x 7>, data !cir.int<s, 65, bitint>, data !s32i, pad 
!cir.array<!u8i x 4>}>
+// LLVM-DAG: %struct.Middle65 = type <{ i8, [7 x i8], i128, i32, [4 x i8] }>
+
+struct Last65 {
+  int i;
+  _BitInt(65) bi;
+};
+// CIR-DAG: !rec_Last65 = !cir.struct<"Last65" packed {data !s32i, pad 
!cir.array<!u8i x 4>, data !cir.int<s, 65, bitint>}>
+// LLVM-DAG: %struct.Last65 = type <{ i32, [4 x i8], i128 }>
+
+struct First127 {
+  _BitInt(127) bi;
+  int i;
+};
+// CIR-DAG: !rec_First127 = !cir.struct<"First127" packed {data !cir.int<s, 
127, bitint>, data !s32i, pad !cir.array<!u8i x 4>}>
+// LLVM-DAG: %struct.First127 = type <{ i128, i32, [4 x i8] }>
+
+struct Middle127 {
+  char c;
+  _BitInt(127) bi;
+  int i;
+};
+// CIR-DAG: !rec_Middle127 = !cir.struct<"Middle127" packed {data !s8i, pad 
!cir.array<!u8i x 7>, data !cir.int<s, 127, bitint>, data !s32i, pad 
!cir.array<!u8i x 4>}>
+// LLVM-DAG: %struct.Middle127 = type <{ i8, [7 x i8], i128, i32, [4 x i8] }>
+
+struct Last127 {
+  int i;
+  _BitInt(127) bi;
+};
+// CIR-DAG: !rec_Last127 = !cir.struct<"Last127" packed {data !s32i, pad 
!cir.array<!u8i x 4>, data !cir.int<s, 127, bitint>}>
+// LLVM-DAG: %struct.Last127 = type <{ i32, [4 x i8], i128 }>
+
+struct First128 {
+  _BitInt(128) bi;
+  int i;
+};
+// CIR-DAG: !rec_First128 = !cir.struct<"First128" packed {data !s128i_bitint, 
data !s32i, pad !cir.array<!u8i x 4>}>
+// LLVM-DAG: %struct.First128 = type <{ i128, i32, [4 x i8] }>
+
+struct Middle128 {
+  char c;
+  _BitInt(128) bi;
+  int i;
+};
+// CIR-DAG: !rec_Middle128 = !cir.struct<"Middle128" packed {data !s8i, pad 
!cir.array<!u8i x 7>, data !s128i_bitint, data !s32i, pad !cir.array<!u8i x 4>}>
+// LLVM-DAG: %struct.Middle128 = type <{ i8, [7 x i8], i128, i32, [4 x i8] }>
+
+struct Last128 {
+  int i;
+  _BitInt(128) bi;
+};
+// CIR-DAG: !rec_Last128 = !cir.struct<"Last128" packed {data !s32i, pad 
!cir.array<!u8i x 4>, data !s128i_bitint}>
+// LLVM-DAG: %struct.Last128 = type <{ i32, [4 x i8], i128 }>
+
+struct ArrMem {
----------------
bcardosolopes wrote:

Every array and nested case here uses `_BitInt(128)`, which is the one width 
where this patch's size change is a no-op: `getStorageTypeWidth(128)` is 
`alignTo(128, 64)` = 128, so only `getMemberAlignment` does any work. The size 
half of the fix, the `getTypeSizeInBits` change flowing through 
`ArrayType::getTypeSizeInBits`'s `getSize() * elementSize`, is only exercised 
by the direct members at 65 and 127.

That is the case I would most want pinned, because it is badly wrong today. 
Built both sides:

```c
struct ArrMem65 { int i; _BitInt(65) bi[2]; };
```

```
before: %struct.ArrMem65 = type { i32, [2 x i128], [15 x i8] }
after:  %struct.ArrMem65 = type <{ i32, [4 x i8], [2 x i128] }>
OGCG:   %struct.ArrMem65 = type <{ i32, [4 x i8], [2 x i128] }>
```

Before the patch the element size multiplies out as 2 x 65 bits = 17 bytes, so 
the array lands unpacked with 15 bytes of tail padding and nothing matches. 
After it, CIR is identical to classic. `ArrMem` with a 65 instead of a 128 is a 
one-line addition and covers the half of the change that nothing else does.

https://github.com/llvm/llvm-project/pull/219487
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to