From f550c29c4e76ccfbdbc8ec2159cf90474530a24c Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 21 Jul 2022 16:50:06 -0700 Subject: LLVM: fix lowering of structs with underaligned fields When lowering a struct type to an LLVM struct type, keep track of whether there are any underaligned fields. If so, then make it a packed llvm struct. This works because we already insert manual padding bytes regardless. We could unconditionally use an LLVM packed struct; the reason we bother checking for underaligned fields is that it is a conservative choice, in case LLVM handles packed structs less optimally. A future improvement could simplify this code by unconditionally using packed LLVM structs and then make sure measure perf is unaffected. closes #12190 --- src/codegen/llvm.zig | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/codegen') diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 9dc20755eb..6ebbd2aaf8 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -2680,11 +2680,15 @@ pub const DeclGen = struct { comptime assert(struct_layout_version == 2); var offset: u64 = 0; var big_align: u32 = 0; + var any_underaligned_fields = false; for (struct_obj.fields.values()) |field| { if (field.is_comptime or !field.ty.hasRuntimeBitsIgnoreComptime()) continue; const field_align = field.normalAlignment(target); + const field_ty_align = field.ty.abiAlignment(target); + any_underaligned_fields = any_underaligned_fields or + field_align < field_ty_align; big_align = @maximum(big_align, field_align); const prev_offset = offset; offset = std.mem.alignForwardGeneric(u64, offset, field_align); @@ -2712,7 +2716,7 @@ pub const DeclGen = struct { llvm_struct_ty.structSetBody( llvm_field_types.items.ptr, @intCast(c_uint, llvm_field_types.items.len), - .False, + llvm.Bool.fromBool(any_underaligned_fields), ); return llvm_struct_ty; -- cgit v1.2.3