================
@@ -26,32 +32,161 @@ struct WrapEmpty {
   int s;
 };
 WrapEmpty w;
-// CIR:      !rec_OuterWithEmpty = !cir.union<"OuterWithEmpty" {!rec_Empty, 
!s32i}>
-// CIR:      !rec_WrapEmpty = !cir.struct<"WrapEmpty" {!rec_OuterWithEmpty, 
!s32i}>
-// CIR:      cir.global external @w = #cir.zero : !rec_WrapEmpty {alignment = 
4 : i64}
+// CIR-DAG: !rec_OuterWithEmpty = !cir.union<"OuterWithEmpty" {!rec_Empty, 
!s32i}>
+// CIR-DAG: !rec_WrapEmpty = !cir.struct<"WrapEmpty" {!rec_OuterWithEmpty, 
!s32i}>
+// CIR-DAG: cir.global external @w = #cir.zero : !rec_WrapEmpty {alignment = 4 
: i64}
 // LLVM-DAG: %struct.WrapEmpty = type { %union.OuterWithEmpty, i32 }
 // LLVM-DAG: %union.OuterWithEmpty = type { i32 }
-// LLVM:     @w = global %struct.WrapEmpty zeroinitializer, align 4
-// OGCG-DAG: %struct.WrapEmpty = type { %union.OuterWithEmpty, i32 }
-// OGCG-DAG: %union.OuterWithEmpty = type { i32 }
-// OGCG:     @w = global %struct.WrapEmpty zeroinitializer, align 4
+// LLVM-DAG: @w = global %struct.WrapEmpty zeroinitializer, align 4
+
+// A union whose only member is itself storage-less.  This one HAS a storage
+// type, so it is the storage member's reported size that must be right.
+union OnlyEmpty {
+  Empty e;
+};
+// CIR-DAG: !rec_OnlyEmpty = !cir.union<"OnlyEmpty" {!rec_Empty}>
+// LLVM-DAG: %union.OnlyEmpty = type { %union.Empty }
+
+// A storage-less union still occupies its own bytes inside a record, so the
+// fields after it must not be pushed past them.
+struct Leading {
+  Empty e;
+  int x;
+};
+
+struct Trailing {
+  int x;
+  Empty e;
+};
+
+struct Middle {
+  int a;
+  Empty e;
+  int b;
+};
+
+struct LeadingOver {
+  EmptyAligned e;
+  int x;
+};
+
+struct LeadingZeroBitfield {
+  OnlyZeroBitfield e;
+  int x;
+};
+
+OnlyEmpty onlyEmpty;
+Leading lead;
+Trailing trail;
+Middle mid;
+LeadingOver leadOver;
+LeadingZeroBitfield leadZero;
+Leading leadArr[2];
+
+// CIR-DAG: !rec_Leading = !cir.struct<"Leading" {!rec_Empty, !s32i}>
+// CIR-DAG: !rec_Trailing = !cir.struct<"Trailing" {!s32i, !rec_Empty}>
+// CIR-DAG: !rec_Middle = !cir.struct<"Middle" {!s32i, !rec_Empty, !s32i}>
+// CIR-DAG: !rec_LeadingOver = !cir.struct<"LeadingOver" padded 
{!rec_EmptyAligned, !s32i, !cir.array<!u8i x 12>}>
+// CIR-DAG: !rec_LeadingZeroBitfield = !cir.struct<"LeadingZeroBitfield" 
{!rec_OnlyZeroBitfield, !s32i}>
+
+// CIR keeps the union's own named type as the record's field and leaves the
+// bytes after it to the LLVM struct layout.  Classic covers the union together
+// with those bytes in one char array.
+// LLVMCIR-DAG: %struct.Leading = type { %union.Empty, i32 }
+// LLVMCIR-DAG: %struct.Trailing = type { i32, %union.Empty }
+// LLVMCIR-DAG: %struct.Middle = type { i32, %union.Empty, i32 }
+// LLVMCIR-DAG: %struct.LeadingZeroBitfield = type { %union.OnlyZeroBitfield, 
i32 }
+// LLVMCIR-DAG: %struct.LeadingOver = type { %union.EmptyAligned, i32, [12 x 
i8] }
+// OGCG-DAG:    %struct.Leading = type { [4 x i8], i32 }
+// OGCG-DAG:    %struct.Trailing = type { i32, [4 x i8] }
+// OGCG-DAG:    %struct.Middle = type { i32, [4 x i8], i32 }
+// OGCG-DAG:    %struct.LeadingZeroBitfield = type { [4 x i8], i32 }
+// OGCG-DAG:    %struct.LeadingOver = type { [16 x i8], i32, [12 x i8] }
+// LLVM-DAG:    @lead = global %struct.Leading zeroinitializer, align 4
+// LLVM-DAG:    @leadOver = global %struct.LeadingOver zeroinitializer, align 
16
 
 void useEmpty() {
   Empty e;
 }
 // CIR: cir.func {{.*}}@_Z8useEmptyv()
 // CIR:   cir.alloca "e" align(1) : !cir.ptr<!rec_Empty>
 // LLVM: define {{.*}} void @_Z8useEmptyv()
-// LLVM:   alloca %union.Empty, i64 1, align 1
-// OGCG: define {{.*}} void @_Z8useEmptyv()
-// OGCG:   alloca %union.Empty, align 1
+// LLVMCIR:   alloca %union.Empty, i64 1, align 1
+// OGCG:      alloca %union.Empty, align 1
 
 void useEmptyAligned() {
   EmptyAligned e;
 }
 // CIR: cir.func {{.*}}@_Z15useEmptyAlignedv()
 // CIR:   cir.alloca "e" align(16) : !cir.ptr<!rec_EmptyAligned>
 // LLVM: define {{.*}} void @_Z15useEmptyAlignedv()
-// LLVM:   alloca %union.EmptyAligned, i64 1, align 16
-// OGCG: define {{.*}} void @_Z15useEmptyAlignedv()
-// OGCG:   alloca %union.EmptyAligned, align 16
+// LLVMCIR:   alloca %union.EmptyAligned, i64 1, align 16
----------------
adams381 wrote:

Same as above.

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

Reply via email to