Commit 2eaef84ebe

Cody Tapscott <topolarity@tapscott.me>
2022-07-12 22:06:51
stage2 llvm: Use unpacked struct for unions and arrays
Our lowerings for various LLVM types assume that we can anticipate the alignment/layout that LLVM will generate. Among other things, this requires that we keep the alignment of our lowered LLVM types synchronized with their expected alignment in Zig. - Arrays were using packed struct types, which is seems to be incorrect since array elements are supposed to be self-aligned. - Unions were using packed struct types for their payload, which causes layout divergence between what stage2 expects and what LLVM generates Consider this lowered union type: ```llvm %Value = type { <{ i64, [8 x i8] }>, i1, [7 x i8] } ; 24 bytes, align(1) %ErrorUnion = type { %Value, i16 } ; 26 bytes, align(2) ``` Zig expects Value to be align(8) and, by extension, for ErrorUnion to be size 32.
1 parent 7090f04
Changed files (1)
src
codegen
src/codegen/llvm.zig
@@ -2689,7 +2689,7 @@ pub const DeclGen = struct {
                         llvm_aligned_field_ty,
                         dg.context.intType(8).arrayType(padding_len),
                     };
-                    break :t dg.context.structType(&fields, fields.len, .True);
+                    break :t dg.context.structType(&fields, fields.len, .False);
                 };
 
                 if (layout.tag_size == 0) {
@@ -3002,7 +3002,7 @@ pub const DeclGen = struct {
                         return dg.context.constStruct(
                             llvm_elems.ptr,
                             @intCast(c_uint, llvm_elems.len),
-                            .True,
+                            .False,
                         );
                     } else {
                         const llvm_elem_ty = try dg.lowerType(elem_ty);
@@ -3039,7 +3039,7 @@ pub const DeclGen = struct {
                         return dg.context.constStruct(
                             llvm_elems.ptr,
                             @intCast(c_uint, llvm_elems.len),
-                            .True,
+                            .False,
                         );
                     } else {
                         const llvm_elem_ty = try dg.lowerType(elem_ty);
@@ -3056,7 +3056,7 @@ pub const DeclGen = struct {
                     const llvm_elems: [1]*const llvm.Value = .{sentinel};
                     const need_unnamed = dg.isUnnamedType(elem_ty, llvm_elems[0]);
                     if (need_unnamed) {
-                        return dg.context.constStruct(&llvm_elems, llvm_elems.len, .True);
+                        return dg.context.constStruct(&llvm_elems, llvm_elems.len, .False);
                     } else {
                         const llvm_elem_ty = try dg.lowerType(elem_ty);
                         return llvm_elem_ty.constArray(&llvm_elems, llvm_elems.len);
@@ -3343,7 +3343,7 @@ pub const DeclGen = struct {
                     const fields: [2]*const llvm.Value = .{
                         field, dg.context.intType(8).arrayType(padding_len).getUndef(),
                     };
-                    break :p dg.context.constStruct(&fields, fields.len, .True);
+                    break :p dg.context.constStruct(&fields, fields.len, .False);
                 };
 
                 if (layout.tag_size == 0) {