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.
This commit is contained in:
Matthew Lugg 2025-11-17 01:36:07 +01:00 committed by Alex Rønne Petersen
parent 891f187032
commit a319211eee
No known key found for this signature in database

View File

@ -3651,35 +3651,22 @@ pub const Object = struct {
.opt => {}, // pointer like optional expected .opt => {}, // pointer like optional expected
else => unreachable, else => unreachable,
} }
const bits = ty.bitSize(zcu);
const bytes: usize = @intCast(std.mem.alignForward(u64, bits, 8) / 8);
var stack = std.heap.stackFallback(32, o.gpa); var stack = std.heap.stackFallback(32, o.gpa);
const allocator = stack.get(); const allocator = stack.get();
const limbs = try allocator.alloc( const bits: usize = @intCast(ty.bitSize(zcu));
std.math.big.Limb,
std.mem.alignForward(usize, bytes, @sizeOf(std.math.big.Limb)) / const buffer = try allocator.alloc(u8, (bits + 7) / 8);
@sizeOf(std.math.big.Limb), defer allocator.free(buffer);
); const limbs = try allocator.alloc(std.math.big.Limb, std.math.big.int.calcTwosCompLimbCount(bits));
defer allocator.free(limbs); defer allocator.free(limbs);
@memset(limbs, 0);
val.writeToPackedMemory(ty, pt, std.mem.sliceAsBytes(limbs)[0..bytes], 0) catch unreachable; val.writeToPackedMemory(ty, pt, buffer, 0) catch unreachable;
if (builtin.target.cpu.arch.endian() == .little) { var big: std.math.big.int.Mutable = .init(limbs, 0);
if (target.cpu.arch.endian() == .big) big.readTwosComplement(buffer, bits, target.cpu.arch.endian(), .unsigned);
std.mem.reverse(u8, std.mem.sliceAsBytes(limbs)[0..bytes]);
} else if (target.cpu.arch.endian() == .little) {
for (limbs) |*limb| {
limb.* = std.mem.nativeToLittle(usize, limb.*);
}
}
return o.builder.bigIntConst(llvm_int_ty, .{ return o.builder.bigIntConst(llvm_int_ty, big.toConst());
.limbs = limbs,
.positive = true,
});
} }
fn lowerValue(o: *Object, pt: Zcu.PerThread, arg_val: InternPool.Index) Error!Builder.Constant { fn lowerValue(o: *Object, pt: Zcu.PerThread, arg_val: InternPool.Index) Error!Builder.Constant {