authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-10-04 07:33:22+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-10-04 07:33:22+02:00
logc2a8df06d70b6683ad9f9bd5590b1e495d6a0b3a
tree778b6a22a74bf08e0be8e4abf0eb7d63d2f9ae44
parentcfa82af363ad1bb6501f629939be5131802c2819
parentadba66435502f0ac7f9cafe610f82960a53997da

Merge pull request 'x86_64: save state after switch_br case comparison' (#36735) from AstraFall/zig:issue-36732 into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/36735 Reviewed-by: Jacob Young <jacobly@ziglang.org>

2 files changed, 16 insertions(+), 2 deletions(-)

src/codegen/x86_64/CodeGen.zig+3-2
...@@ -177120,8 +177120,6 @@ fn lowerSwitchBr(...@@ -177120,8 +177120,6 @@ fn lowerSwitchBr(
177120 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), cg.gpa);177120 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), cg.gpa);
177121 const allocator = bfa.allocator();177121 const allocator = bfa.allocator();
177122177122
177123 const state = try cg.saveState();
177124
177125 const liveness = try cg.liveness.getSwitchBr(allocator, inst, switch_br.cases_len + 1);177123 const liveness = try cg.liveness.getSwitchBr(allocator, inst, switch_br.cases_len + 1);
177126 defer allocator.free(liveness.deaths);177124 defer allocator.free(liveness.deaths);
177127177125
...@@ -177232,6 +177230,7 @@ fn lowerSwitchBr(...@@ -177232,6 +177230,7 @@ fn lowerSwitchBr(
177232 }177230 }
177233 };177231 };
177234 var cases_it = switch_br.iterateCases();177232 var cases_it = switch_br.iterateCases();
177233 const state = try cg.saveState();
177235 while (cases_it.next()) |case| {177234 while (cases_it.next()) |case| {
177236 {177235 {
177237 const table = cg.mir_table.items[table_start..][0..table_len];177236 const table = cg.mir_table.items[table_start..][0..table_len];
...@@ -177388,6 +177387,7 @@ fn lowerSwitchBr(...@@ -177388,6 +177387,7 @@ fn lowerSwitchBr(
177388177387
177389 // The jump to skip this case if the conditions all failed.177388 // The jump to skip this case if the conditions all failed.
177390 const skip_case_reloc = try cg.asmJmpReloc(undefined);177389 const skip_case_reloc = try cg.asmJmpReloc(undefined);
177390 const state = try cg.saveState();
177391177391
177392 for (liveness.deaths[case.idx]) |operand| try cg.processDeath(operand, .{});177392 for (liveness.deaths[case.idx]) |operand| try cg.processDeath(operand, .{});
177393177393
...@@ -177406,6 +177406,7 @@ fn lowerSwitchBr(...@@ -177406,6 +177406,7 @@ fn lowerSwitchBr(
177406 }177406 }
177407 if (switch_br.else_body_len > 0) {177407 if (switch_br.else_body_len > 0) {
177408 const else_body = cases_it.elseBody();177408 const else_body = cases_it.elseBody();
177409 const state = try cg.saveState();
177409177410
177410 const else_deaths = liveness.deaths.len - 1;177411 const else_deaths = liveness.deaths.len - 1;
177411 for (liveness.deaths[else_deaths]) |operand| try cg.processDeath(operand, .{});177412 for (liveness.deaths[else_deaths]) |operand| try cg.processDeath(operand, .{});
test/behavior/switch.zig+13
...@@ -1568,3 +1568,16 @@ test "union field pointer capture preserves alignment in inline prong" {...@@ -1568,3 +1568,16 @@ test "union field pointer capture preserves alignment in inline prong" {
1568 try comptime U.doTheTest(&.{ .a = 123 });1568 try comptime U.doTheTest(&.{ .a = 123 });
1569 try comptime U.doTheTest(&.{ .b = 123 });1569 try comptime U.doTheTest(&.{ .b = 123 });
1570}1570}
1571
1572test "switch on expression" {
1573 var a: []const []const u8 = &.{ "b", "b", "A", "A", "b" };
1574 _ = &a;
1575 var c: isize = 0;
1576 for (a[1..]) |b| {
1577 switch (b[0] % 2) {
1578 0 => c += 1,
1579 else => c -= 1,
1580 }
1581 }
1582 try expect(c == 0);
1583}