From c030ec1884ad7c553d6680944b47a1fc7653586f Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 30 Jun 2022 15:58:51 -0700 Subject: LLVM: use unnamed struct llvm type for unions when necessary The constant value lowering for unions was missing a check for whether the payload was itself an unnamed struct. Lowerings of other types already handle this case. closes #11971 --- src/codegen/llvm.zig | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/codegen') diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 7f85570e06..45a90c81e5 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -3401,6 +3401,13 @@ pub const DeclGen = struct { const union_obj = tv.ty.cast(Type.Payload.Union).?.data; const field_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag, dg.module).?; assert(union_obj.haveFieldTypes()); + + // Sometimes we must make an unnamed struct because LLVM does + // not support bitcasting our payload struct to the true union payload type. + // Instead we use an unnamed struct and every reference to the global + // must pointer cast to the expected type before accessing the union. + var need_unnamed: bool = layout.most_aligned_field != field_index; + const field_ty = union_obj.fields.values()[field_index].ty; const payload = p: { if (!field_ty.hasRuntimeBitsIgnoreComptime()) { @@ -3408,6 +3415,7 @@ pub const DeclGen = struct { break :p dg.context.intType(8).arrayType(padding_len).getUndef(); } const field = try lowerValue(dg, .{ .ty = field_ty, .val = tag_and_val.val }); + need_unnamed = need_unnamed or dg.isUnnamedType(field_ty, field); const field_size = field_ty.abiSize(target); if (field_size == layout.payload_size) { break :p field; @@ -3419,12 +3427,6 @@ pub const DeclGen = struct { break :p dg.context.constStruct(&fields, fields.len, .True); }; - // In this case we must make an unnamed struct because LLVM does - // not support bitcasting our payload struct to the true union payload type. - // Instead we use an unnamed struct and every reference to the global - // must pointer cast to the expected type before accessing the union. - const need_unnamed = layout.most_aligned_field != field_index; - if (layout.tag_size == 0) { const fields: [1]*const llvm.Value = .{payload}; if (need_unnamed) { -- cgit v1.2.3 From d3542be875704bffc931970948345d1a44e25b8e Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 30 Jun 2022 16:32:03 -0700 Subject: LLVM: be sure to never pass align(0) attribute This can happen with pointers to zero-bit types. This commit fixes an LLVM assertion being tripped. --- src/codegen/llvm.zig | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/codegen') diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 45a90c81e5..c3194ccda1 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -768,7 +768,11 @@ pub const Object = struct { if (ptr_info.@"align" != 0) { dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align"); } else { - dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.pointee_type.abiAlignment(target)); + const elem_align = @maximum( + ptr_info.pointee_type.abiAlignment(target), + 1, + ); + dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", elem_align); } } } @@ -840,7 +844,8 @@ pub const Object = struct { if (ptr_info.@"align" != 0) { dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align"); } else { - dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.pointee_type.abiAlignment(target)); + const elem_align = @maximum(ptr_info.pointee_type.abiAlignment(target), 1); + dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", elem_align); } const ptr_param = llvm_func.getParam(llvm_arg_i); llvm_arg_i += 1; -- cgit v1.2.3