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 {
36513651 .opt => {}, // pointer like optional expected
36523652 else => unreachable,
36533653 }
3654 const bits = ty.bitSize(zcu);
3655 const bytes: usize = @intCast(std.mem.alignForward(u64, bits, 8) / 8);
3656
36573654 var stack = std.heap.stackFallback(32, o.gpa);
36583655 const allocator = stack.get();
36593656
3660 const limbs = try allocator.alloc(
3661 std.math.big.Limb,
3662 std.mem.alignForward(usize, bytes, @sizeOf(std.math.big.Limb)) /
3663 @sizeOf(std.math.big.Limb),
3664 );
3657 const bits: usize = @intCast(ty.bitSize(zcu));
3658
3659 const buffer = try allocator.alloc(u8, (bits + 7) / 8);
3660 defer allocator.free(buffer);
3661 const limbs = try allocator.alloc(std.math.big.Limb, std.math.big.int.calcTwosCompLimbCount(bits));
36653662 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) {
3671 if (target.cpu.arch.endian() == .big)
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 }
3666 var big: std.math.big.int.Mutable = .init(limbs, 0);
3667 big.readTwosComplement(buffer, bits, target.cpu.arch.endian(), .unsigned);
36783668
3679 return o.builder.bigIntConst(llvm_int_ty, .{
3680 .limbs = limbs,
3681 .positive = true,
3682 });
3669 return o.builder.bigIntConst(llvm_int_ty, big.toConst());
36833670 }
36843671
36853672 fn lowerValue(o: *Object, pt: Zcu.PerThread, arg_val: InternPool.Index) Error!Builder.Constant {