x86_64: fix switch on big ints

This commit is contained in:
Jacob Young 2025-03-26 14:40:00 -04:00
parent bc10131db1
commit 1eb5d70d12
2 changed files with 6 additions and 8 deletions

View File

@ -102890,9 +102890,6 @@ fn lowerSwitchBr(
const relocs = try allocator.alloc(Mir.Inst.Index, case.items.len + case.ranges.len); const relocs = try allocator.alloc(Mir.Inst.Index, case.items.len + case.ranges.len);
defer allocator.free(relocs); defer allocator.free(relocs);
var cond_temp = try cg.tempInit(condition_ty, condition);
const reset_index = cg.next_temp_index;
try cg.spillEflagsIfOccupied(); try cg.spillEflagsIfOccupied();
for (case.items, relocs[0..case.items.len]) |item, *reloc| { for (case.items, relocs[0..case.items.len]) |item, *reloc| {
const item_mcv = try cg.resolveInst(item); const item_mcv = try cg.resolveInst(item);
@ -102903,6 +102900,7 @@ fn lowerSwitchBr(
else => unreachable, else => unreachable,
}, },
else => cc: { else => cc: {
var cond_temp = try cg.tempInit(condition_ty, condition);
var item_temp = try cg.tempInit(condition_ty, item_mcv); var item_temp = try cg.tempInit(condition_ty, item_mcv);
const cc_temp = cond_temp.cmpInts(.eq, &item_temp, cg) catch |err| switch (err) { const cc_temp = cond_temp.cmpInts(.eq, &item_temp, cg) catch |err| switch (err) {
error.SelectFailed => unreachable, error.SelectFailed => unreachable,
@ -102911,7 +102909,8 @@ fn lowerSwitchBr(
try item_temp.die(cg); try item_temp.die(cg);
const cc = cc_temp.tracking(cg).short.eflags; const cc = cc_temp.tracking(cg).short.eflags;
try cc_temp.die(cg); try cc_temp.die(cg);
try cg.resetTemps(reset_index); try cond_temp.die(cg);
try cg.resetTemps(@enumFromInt(0));
break :cc cc; break :cc cc;
}, },
}; };
@ -102919,6 +102918,7 @@ fn lowerSwitchBr(
} }
for (case.ranges, relocs[case.items.len..]) |range, *reloc| { 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 min_mcv = try cg.resolveInst(range[0]);
const max_mcv = try cg.resolveInst(range[1]); const max_mcv = try cg.resolveInst(range[1]);
// `null` means always false. // `null` means always false.
@ -102962,7 +102962,8 @@ fn lowerSwitchBr(
break :cc cc; break :cc cc;
}, },
}; };
try cg.resetTemps(reset_index); try cond_temp.die(cg);
try cg.resetTemps(@enumFromInt(0));
// "Success" case is in `reloc`.... // "Success" case is in `reloc`....
if (lte_max) |cc| { if (lte_max) |cc| {
reloc.* = try cg.asmJccReloc(cc, undefined); reloc.* = try cg.asmJccReloc(cc, undefined);
@ -102973,8 +102974,6 @@ fn lowerSwitchBr(
if (lt_min_reloc) |r| cg.performReloc(r); if (lt_min_reloc) |r| cg.performReloc(r);
} }
try cond_temp.die(cg);
try cg.resetTemps(@enumFromInt(0));
cg.checkInvariantsAfterAirInst(); cg.checkInvariantsAfterAirInst();
// The jump to skip this case if the conditions all failed. // The jump to skip this case if the conditions all failed.

View File

@ -43,7 +43,6 @@ fn testSwitchWithAllRanges(x: u32, y: u32) u32 {
} }
test "switch arbitrary int size" { 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_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO