Skip to content

Commit 0c438ab

Browse files
committed
x86_64: hotfix for crash during in-memory coercion of large type
Unblocks ziglang#15768 Closes ziglang#15904
1 parent 706bdf6 commit 0c438ab

File tree

2 files changed

+25
-25
lines changed

2 files changed

+25
-25
lines changed

src/arch/x86_64/CodeGen.zig

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10175,37 +10175,38 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
1017510175
if (dst_ty.isAbiInt()) dst_ty.intInfo(self.target.*).signedness else .unsigned;
1017610176
const src_signedness =
1017710177
if (src_ty.isAbiInt()) src_ty.intInfo(self.target.*).signedness else .unsigned;
10178+
if (dst_signedness == src_signedness) break :result dst_mcv;
10179+
1017810180
const abi_size = @intCast(u16, dst_ty.abiSize(self.target.*));
1017910181
const bit_size = @intCast(u16, dst_ty.bitSize(self.target.*));
10180-
const dst_limbs_len = math.divCeil(u16, bit_size, 64) catch unreachable;
10181-
if (dst_signedness != src_signedness and abi_size * 8 > bit_size) {
10182-
const high_reg = if (dst_mcv.isRegister())
10183-
dst_mcv.getReg().?
10184-
else
10185-
try self.copyToTmpRegister(
10186-
Type.usize,
10187-
dst_mcv.address().offset((dst_limbs_len - 1) * 8).deref(),
10188-
);
10189-
const high_lock = self.register_manager.lockReg(high_reg);
10190-
defer if (high_lock) |lock| self.register_manager.unlockReg(lock);
10191-
10192-
var high_pl = Type.Payload.Bits{
10193-
.base = .{ .tag = switch (dst_signedness) {
10194-
.signed => .int_signed,
10195-
.unsigned => .int_unsigned,
10196-
} },
10197-
.data = bit_size % 64,
10198-
};
10199-
const high_ty = Type.initPayload(&high_pl.base);
10182+
if (abi_size * 8 <= bit_size) break :result dst_mcv;
1020010183

10201-
try self.truncateRegister(high_ty, high_reg);
10202-
if (!dst_mcv.isRegister()) try self.genCopy(
10184+
const dst_limbs_len = math.divCeil(i32, bit_size, 64) catch unreachable;
10185+
const high_reg = if (dst_mcv.isRegister())
10186+
dst_mcv.getReg().?
10187+
else
10188+
try self.copyToTmpRegister(
1020310189
Type.usize,
1020410190
dst_mcv.address().offset((dst_limbs_len - 1) * 8).deref(),
10205-
.{ .register = high_reg },
1020610191
);
10207-
}
10192+
const high_lock = self.register_manager.lockReg(high_reg);
10193+
defer if (high_lock) |lock| self.register_manager.unlockReg(lock);
10194+
10195+
var high_pl = Type.Payload.Bits{
10196+
.base = .{ .tag = switch (dst_signedness) {
10197+
.signed => .int_signed,
10198+
.unsigned => .int_unsigned,
10199+
} },
10200+
.data = bit_size % 64,
10201+
};
10202+
const high_ty = Type.initPayload(&high_pl.base);
1020810203

10204+
try self.truncateRegister(high_ty, high_reg);
10205+
if (!dst_mcv.isRegister()) try self.genCopy(
10206+
Type.usize,
10207+
dst_mcv.address().offset((dst_limbs_len - 1) * 8).deref(),
10208+
.{ .register = high_reg },
10209+
);
1020910210
break :result dst_mcv;
1021010211
};
1021110212
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });

test/behavior/maximum_minimum.zig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,6 @@ test "@min/@max notices vector bounds" {
197197

198198
test "@min/@max on comptime_int" {
199199
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
200-
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
201200
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
202201
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
203202
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO

0 commit comments

Comments
 (0)