Commit 0c438ab616

Jacob Young <jacobly0@users.noreply.github.com>
2023-05-30 03:45:25
x86_64: hotfix for crash during in-memory coercion of large type
Unblocks #15768 Closes #15904
1 parent 706bdf6
Changed files (2)
src
arch
test
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);
-
-            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);
+        if (abi_size * 8 <= bit_size) break :result dst_mcv;
 
-            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 });
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