authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-29 21:45:25-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-29 22:03:27-04:00
log0c438ab61635d1354e454b918a06341cff4821d5
tree2e0ff45defc5cc828246c92548b92ba701311535
parent706bdf6512aec9f5d003cc2ec64ba16ac0a202dc

x86_64: hotfix for crash during in-memory coercion of large type

Unblocks #15768 Closes #15904

2 files changed, 25 insertions(+), 25 deletions(-)

src/arch/x86_64/CodeGen.zig+25-24
......@@ -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-1
......@@ -197,7 +197,6 @@ test "@min/@max notices vector bounds" {
197197
198198test "@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