From 0c438ab61635d1354e454b918a06341cff4821d5 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Mon, 29 May 2023 21:45:25 -0400 Subject: [PATCH] x86_64: hotfix for crash during in-memory coercion of large type Unblocks #15768 Closes #15904 --- src/arch/x86_64/CodeGen.zig | 49 ++++++++++++++++--------------- test/behavior/maximum_minimum.zig | 1 - 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 05d5da107f..59c6551de1 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -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 }); diff --git a/test/behavior/maximum_minimum.zig b/test/behavior/maximum_minimum.zig index 2750dbdb6f..932a904421 100644 --- a/test/behavior/maximum_minimum.zig +++ b/test/behavior/maximum_minimum.zig @@ -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