Commit 1eb5d70d12

Jacob Young <jacobly0@users.noreply.github.com>
2025-03-26 19:40:00
x86_64: fix switch on big ints
1 parent bc10131
Changed files (2)
src
arch
test
behavior
src/arch/x86_64/CodeGen.zig
@@ -102890,9 +102890,6 @@ fn lowerSwitchBr(
         const relocs = try allocator.alloc(Mir.Inst.Index, case.items.len + case.ranges.len);
         defer allocator.free(relocs);
 
-        var cond_temp = try cg.tempInit(condition_ty, condition);
-        const reset_index = cg.next_temp_index;
-
         try cg.spillEflagsIfOccupied();
         for (case.items, relocs[0..case.items.len]) |item, *reloc| {
             const item_mcv = try cg.resolveInst(item);
@@ -102903,6 +102900,7 @@ fn lowerSwitchBr(
                     else => unreachable,
                 },
                 else => cc: {
+                    var cond_temp = try cg.tempInit(condition_ty, condition);
                     var item_temp = try cg.tempInit(condition_ty, item_mcv);
                     const cc_temp = cond_temp.cmpInts(.eq, &item_temp, cg) catch |err| switch (err) {
                         error.SelectFailed => unreachable,
@@ -102911,7 +102909,8 @@ fn lowerSwitchBr(
                     try item_temp.die(cg);
                     const cc = cc_temp.tracking(cg).short.eflags;
                     try cc_temp.die(cg);
-                    try cg.resetTemps(reset_index);
+                    try cond_temp.die(cg);
+                    try cg.resetTemps(@enumFromInt(0));
                     break :cc cc;
                 },
             };
@@ -102919,6 +102918,7 @@ fn lowerSwitchBr(
         }
 
         for (case.ranges, relocs[case.items.len..]) |range, *reloc| {
+            var cond_temp = try cg.tempInit(condition_ty, condition);
             const min_mcv = try cg.resolveInst(range[0]);
             const max_mcv = try cg.resolveInst(range[1]);
             // `null` means always false.
@@ -102962,7 +102962,8 @@ fn lowerSwitchBr(
                     break :cc cc;
                 },
             };
-            try cg.resetTemps(reset_index);
+            try cond_temp.die(cg);
+            try cg.resetTemps(@enumFromInt(0));
             // "Success" case is in `reloc`....
             if (lte_max) |cc| {
                 reloc.* = try cg.asmJccReloc(cc, undefined);
@@ -102973,8 +102974,6 @@ fn lowerSwitchBr(
             if (lt_min_reloc) |r| cg.performReloc(r);
         }
 
-        try cond_temp.die(cg);
-        try cg.resetTemps(@enumFromInt(0));
         cg.checkInvariantsAfterAirInst();
 
         // The jump to skip this case if the conditions all failed.
test/behavior/switch.zig
@@ -43,7 +43,6 @@ fn testSwitchWithAllRanges(x: u32, y: u32) u32 {
 }
 
 test "switch arbitrary int size" {
-    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