From f880af369d4814df7cd1ec0ef5f85343108bbe81 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 27 Jul 2022 13:22:33 -0700 Subject: LLVM: fix lowering byte-aligned packed struct field pointers --- src/codegen/llvm.zig | 18 ++++++++++++++++++ src/codegen/llvm/bindings.zig | 3 +++ 2 files changed, 21 insertions(+) (limited to 'src/codegen') diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index e7915e08b3..6ebe76fb39 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -3646,6 +3646,24 @@ pub const DeclGen = struct { }, .Struct => { const field_ty = parent_ty.structFieldType(field_index); + if (parent_ty.containerLayout() == .Packed) { + const llvm_usize = dg.context.intType(target.cpu.arch.ptrBitWidth()); + const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize); + // count bits of fields before this one + const prev_bits = b: { + var b: usize = 0; + for (parent_ty.structFields().values()[0..field_index]) |field| { + if (field.is_comptime or !field.ty.hasRuntimeBitsIgnoreComptime()) continue; + b += field.ty.bitSize(target); + } + break :b b; + }; + const byte_offset = llvm_usize.constInt((prev_bits + 7) / 8, .False); + const field_addr = base_addr.constAdd(byte_offset); + bitcast_needed = false; + const final_llvm_ty = (try dg.lowerType(ptr_child_ty)).pointerType(0); + break :blk field_addr.constIntToPtr(final_llvm_ty); + } bitcast_needed = !field_ty.eql(ptr_child_ty, dg.module); var ty_buf: Type.Payload.Pointer = undefined; diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig index 07408f12b9..e4357b8060 100644 --- a/src/codegen/llvm/bindings.zig +++ b/src/codegen/llvm/bindings.zig @@ -169,6 +169,9 @@ pub const Value = opaque { pub const constNot = LLVMConstNot; extern fn LLVMConstNot(ConstantVal: *const Value) *const Value; + pub const constAdd = LLVMConstAdd; + extern fn LLVMConstAdd(LHSConstant: *const Value, RHSConstant: *const Value) *const Value; + pub const setWeak = LLVMSetWeak; extern fn LLVMSetWeak(CmpXchgInst: *const Value, IsWeak: Bool) void; -- cgit v1.2.3