zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 2eaef84ebe968224b0cf25206abf12ea1c5e0f5a (tree)
parent 7090f0471c0169c60a9476b537b09eebe1bdf6af
Author: Cody Tapscott <topolarity@tapscott.me>
Date:   Tue, 12 Jul 2022 13:06:51 -0700

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.

Diffstat:
Msrc/codegen/llvm.zig | 10+++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/codegen/llvm.zig b/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) {