authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-03-26 14:40:00-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-04-09 20:14:12-04:00
log1eb5d70d1261be143a5f3c1a73ea23335d8c0df6
treeba3632b41ae93dd7b63d3c97c1d0d0f52e0c5e43
parentbc10131db11fad281163a53c4702873047cb9223

x86_64: fix switch on big ints


2 files changed, 6 insertions(+), 8 deletions(-)

src/arch/x86_64/CodeGen.zig+6-7
...@@ -102890,9 +102890,6 @@ fn lowerSwitchBr(...@@ -102890,9 +102890,6 @@ fn lowerSwitchBr(
102890 const relocs = try allocator.alloc(Mir.Inst.Index, case.items.len + case.ranges.len);102890 const relocs = try allocator.alloc(Mir.Inst.Index, case.items.len + case.ranges.len);
102891 defer allocator.free(relocs);102891 defer allocator.free(relocs);
102892102892
102893 var cond_temp = try cg.tempInit(condition_ty, condition);
102894 const reset_index = cg.next_temp_index;
102895
102896 try cg.spillEflagsIfOccupied();102893 try cg.spillEflagsIfOccupied();
102897 for (case.items, relocs[0..case.items.len]) |item, *reloc| {102894 for (case.items, relocs[0..case.items.len]) |item, *reloc| {
102898 const item_mcv = try cg.resolveInst(item);102895 const item_mcv = try cg.resolveInst(item);
...@@ -102903,6 +102900,7 @@ fn lowerSwitchBr(...@@ -102903,6 +102900,7 @@ fn lowerSwitchBr(
102903 else => unreachable,102900 else => unreachable,
102904 },102901 },
102905 else => cc: {102902 else => cc: {
102903 var cond_temp = try cg.tempInit(condition_ty, condition);
102906 var item_temp = try cg.tempInit(condition_ty, item_mcv);102904 var item_temp = try cg.tempInit(condition_ty, item_mcv);
102907 const cc_temp = cond_temp.cmpInts(.eq, &item_temp, cg) catch |err| switch (err) {102905 const cc_temp = cond_temp.cmpInts(.eq, &item_temp, cg) catch |err| switch (err) {
102908 error.SelectFailed => unreachable,102906 error.SelectFailed => unreachable,
...@@ -102911,7 +102909,8 @@ fn lowerSwitchBr(...@@ -102911,7 +102909,8 @@ fn lowerSwitchBr(
102911 try item_temp.die(cg);102909 try item_temp.die(cg);
102912 const cc = cc_temp.tracking(cg).short.eflags;102910 const cc = cc_temp.tracking(cg).short.eflags;
102913 try cc_temp.die(cg);102911 try cc_temp.die(cg);
102914 try cg.resetTemps(reset_index);102912 try cond_temp.die(cg);
102913 try cg.resetTemps(@enumFromInt(0));
102915 break :cc cc;102914 break :cc cc;
102916 },102915 },
102917 };102916 };
...@@ -102919,6 +102918,7 @@ fn lowerSwitchBr(...@@ -102919,6 +102918,7 @@ fn lowerSwitchBr(
102919 }102918 }
102920102919
102921 for (case.ranges, relocs[case.items.len..]) |range, *reloc| {102920 for (case.ranges, relocs[case.items.len..]) |range, *reloc| {
102921 var cond_temp = try cg.tempInit(condition_ty, condition);
102922 const min_mcv = try cg.resolveInst(range[0]);102922 const min_mcv = try cg.resolveInst(range[0]);
102923 const max_mcv = try cg.resolveInst(range[1]);102923 const max_mcv = try cg.resolveInst(range[1]);
102924 // `null` means always false.102924 // `null` means always false.
...@@ -102962,7 +102962,8 @@ fn lowerSwitchBr(...@@ -102962,7 +102962,8 @@ fn lowerSwitchBr(
102962 break :cc cc;102962 break :cc cc;
102963 },102963 },
102964 };102964 };
102965 try cg.resetTemps(reset_index);102965 try cond_temp.die(cg);
102966 try cg.resetTemps(@enumFromInt(0));
102966 // "Success" case is in `reloc`....102967 // "Success" case is in `reloc`....
102967 if (lte_max) |cc| {102968 if (lte_max) |cc| {
102968 reloc.* = try cg.asmJccReloc(cc, undefined);102969 reloc.* = try cg.asmJccReloc(cc, undefined);
...@@ -102973,8 +102974,6 @@ fn lowerSwitchBr(...@@ -102973,8 +102974,6 @@ fn lowerSwitchBr(
102973 if (lt_min_reloc) |r| cg.performReloc(r);102974 if (lt_min_reloc) |r| cg.performReloc(r);
102974 }102975 }
102975102976
102976 try cond_temp.die(cg);
102977 try cg.resetTemps(@enumFromInt(0));
102978 cg.checkInvariantsAfterAirInst();102977 cg.checkInvariantsAfterAirInst();
102979102978
102980 // The jump to skip this case if the conditions all failed.102979 // The jump to skip this case if the conditions all failed.
test/behavior/switch.zig-1
...@@ -43,7 +43,6 @@ fn testSwitchWithAllRanges(x: u32, y: u32) u32 {...@@ -43,7 +43,6 @@ fn testSwitchWithAllRanges(x: u32, y: u32) u32 {
43}43}
4444
45test "switch arbitrary int size" {45test "switch arbitrary int size" {
46 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
47 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO46 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
48 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO47 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
49 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO48 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO