x86_64: hotfix for crash during in-memory coercion of large type
Unblocks #15768 Closes #15904
This commit is contained in:
@@ -10175,37 +10175,38 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
|
||||
if (dst_ty.isAbiInt()) dst_ty.intInfo(self.target.*).signedness else .unsigned;
|
||||
const src_signedness =
|
||||
if (src_ty.isAbiInt()) src_ty.intInfo(self.target.*).signedness else .unsigned;
|
||||
if (dst_signedness == src_signedness) break :result dst_mcv;
|
||||
|
||||
const abi_size = @intCast(u16, dst_ty.abiSize(self.target.*));
|
||||
const bit_size = @intCast(u16, dst_ty.bitSize(self.target.*));
|
||||
const dst_limbs_len = math.divCeil(u16, bit_size, 64) catch unreachable;
|
||||
if (dst_signedness != src_signedness and abi_size * 8 > bit_size) {
|
||||
const high_reg = if (dst_mcv.isRegister())
|
||||
dst_mcv.getReg().?
|
||||
else
|
||||
try self.copyToTmpRegister(
|
||||
Type.usize,
|
||||
dst_mcv.address().offset((dst_limbs_len - 1) * 8).deref(),
|
||||
);
|
||||
const high_lock = self.register_manager.lockReg(high_reg);
|
||||
defer if (high_lock) |lock| self.register_manager.unlockReg(lock);
|
||||
if (abi_size * 8 <= bit_size) break :result dst_mcv;
|
||||
|
||||
var high_pl = Type.Payload.Bits{
|
||||
.base = .{ .tag = switch (dst_signedness) {
|
||||
.signed => .int_signed,
|
||||
.unsigned => .int_unsigned,
|
||||
} },
|
||||
.data = bit_size % 64,
|
||||
};
|
||||
const high_ty = Type.initPayload(&high_pl.base);
|
||||
|
||||
try self.truncateRegister(high_ty, high_reg);
|
||||
if (!dst_mcv.isRegister()) try self.genCopy(
|
||||
const dst_limbs_len = math.divCeil(i32, bit_size, 64) catch unreachable;
|
||||
const high_reg = if (dst_mcv.isRegister())
|
||||
dst_mcv.getReg().?
|
||||
else
|
||||
try self.copyToTmpRegister(
|
||||
Type.usize,
|
||||
dst_mcv.address().offset((dst_limbs_len - 1) * 8).deref(),
|
||||
.{ .register = high_reg },
|
||||
);
|
||||
}
|
||||
const high_lock = self.register_manager.lockReg(high_reg);
|
||||
defer if (high_lock) |lock| self.register_manager.unlockReg(lock);
|
||||
|
||||
var high_pl = Type.Payload.Bits{
|
||||
.base = .{ .tag = switch (dst_signedness) {
|
||||
.signed => .int_signed,
|
||||
.unsigned => .int_unsigned,
|
||||
} },
|
||||
.data = bit_size % 64,
|
||||
};
|
||||
const high_ty = Type.initPayload(&high_pl.base);
|
||||
|
||||
try self.truncateRegister(high_ty, high_reg);
|
||||
if (!dst_mcv.isRegister()) try self.genCopy(
|
||||
Type.usize,
|
||||
dst_mcv.address().offset((dst_limbs_len - 1) * 8).deref(),
|
||||
.{ .register = high_reg },
|
||||
);
|
||||
break :result dst_mcv;
|
||||
};
|
||||
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
|
||||
|
||||
@@ -197,7 +197,6 @@ test "@min/@max notices vector bounds" {
|
||||
|
||||
test "@min/@max on comptime_int" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
Reference in New Issue
Block a user