authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-11-17 01:36:07+01:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-11-19 01:42:37+01:00
loga319211eeed8aca295912c5a484ed4d389d36918
treeec6657e8a1e895f700ad1d166e39a0929a957e37
parent891f1870320000205291940ba2e276c1fa043cd0
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

llvm: fix lowering of packed struct constants

The big-endian logic here was simply incorrect. Luckily, it was also overcomplicated; after calling `Value.writeToPackedMemory`, there is a method on `std.math.big.int.Mutable` which just does the correct endianness load for us.

1 files changed, 9 insertions(+), 22 deletions(-)

src/codegen/llvm.zig+9-22
...@@ -3651,35 +3651,22 @@ pub const Object = struct {...@@ -3651,35 +3651,22 @@ pub const Object = struct {
3651 .opt => {}, // pointer like optional expected3651 .opt => {}, // pointer like optional expected
3652 else => unreachable,3652 else => unreachable,
3653 }3653 }
3654 const bits = ty.bitSize(zcu);
3655 const bytes: usize = @intCast(std.mem.alignForward(u64, bits, 8) / 8);
3656
3657 var stack = std.heap.stackFallback(32, o.gpa);3654 var stack = std.heap.stackFallback(32, o.gpa);
3658 const allocator = stack.get();3655 const allocator = stack.get();
36593656
3660 const limbs = try allocator.alloc(3657 const bits: usize = @intCast(ty.bitSize(zcu));
3661 std.math.big.Limb,3658
3662 std.mem.alignForward(usize, bytes, @sizeOf(std.math.big.Limb)) /3659 const buffer = try allocator.alloc(u8, (bits + 7) / 8);
3663 @sizeOf(std.math.big.Limb),3660 defer allocator.free(buffer);
3664 );3661 const limbs = try allocator.alloc(std.math.big.Limb, std.math.big.int.calcTwosCompLimbCount(bits));
3665 defer allocator.free(limbs);3662 defer allocator.free(limbs);
3666 @memset(limbs, 0);
36673663
3668 val.writeToPackedMemory(ty, pt, std.mem.sliceAsBytes(limbs)[0..bytes], 0) catch unreachable;3664 val.writeToPackedMemory(ty, pt, buffer, 0) catch unreachable;
36693665
3670 if (builtin.target.cpu.arch.endian() == .little) {3666 var big: std.math.big.int.Mutable = .init(limbs, 0);
3671 if (target.cpu.arch.endian() == .big)3667 big.readTwosComplement(buffer, bits, target.cpu.arch.endian(), .unsigned);
3672 std.mem.reverse(u8, std.mem.sliceAsBytes(limbs)[0..bytes]);
3673 } else if (target.cpu.arch.endian() == .little) {
3674 for (limbs) |*limb| {
3675 limb.* = std.mem.nativeToLittle(usize, limb.*);
3676 }
3677 }
36783668
3679 return o.builder.bigIntConst(llvm_int_ty, .{3669 return o.builder.bigIntConst(llvm_int_ty, big.toConst());
3680 .limbs = limbs,
3681 .positive = true,
3682 });
3683 }3670 }
36843671
3685 fn lowerValue(o: *Object, pt: Zcu.PerThread, arg_val: InternPool.Index) Error!Builder.Constant {3672 fn lowerValue(o: *Object, pt: Zcu.PerThread, arg_val: InternPool.Index) Error!Builder.Constant {