authorgravatar for xtex@astrafall.orgxtex <xtex@astrafall.org> 2026-09-02 13:23:12+08:00
committergravatar for xtex@astrafall.orgxtex <xtex@astrafall.org> 2026-10-03 15:20:14+08:00
logd81bdd8ab9092b844c974d0ab6dfe150cbf18f8d
tree127b98b1ad27c485795e80d3b8a5d4bb4b466122
parent1926e8c679dcf2264cd8af9f5bb1a62b8938c41f
signature Signed by SSH key SHA256:IEYEjkZlkUTr5U9GiDAmZU/4eZus2t2RsxusyhQqwao

x86_64: save state after switch_br case comparison

After each case body, lowerSwitchBr restores tracking state without emitting actual instructions, as state changes made in the body block can be forgotten safely. However, previously, the state was saved before generating the case condition code, leading to changes generated during the item comparison being discarded, breaking following cases. Fixes: #36732

1 files changed, 3 insertions(+), 2 deletions(-)

src/codegen/x86_64/CodeGen.zig+3-2
......@@ -177120,8 +177120,6 @@ fn lowerSwitchBr(
177120177120 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), cg.gpa);
177121177121 const allocator = bfa.allocator();
177122177122
177123 const state = try cg.saveState();
177124
177125177123 const liveness = try cg.liveness.getSwitchBr(allocator, inst, switch_br.cases_len + 1);
177126177124 defer allocator.free(liveness.deaths);
177127177125
......@@ -177232,6 +177230,7 @@ fn lowerSwitchBr(
177232177230 }
177233177231 };
177234177232 var cases_it = switch_br.iterateCases();
177233 const state = try cg.saveState();
177235177234 while (cases_it.next()) |case| {
177236177235 {
177237177236 const table = cg.mir_table.items[table_start..][0..table_len];
......@@ -177388,6 +177387,7 @@ fn lowerSwitchBr(
177388177387
177389177388 // The jump to skip this case if the conditions all failed.
177390177389 const skip_case_reloc = try cg.asmJmpReloc(undefined);
177390 const state = try cg.saveState();
177391177391
177392177392 for (liveness.deaths[case.idx]) |operand| try cg.processDeath(operand, .{});
177393177393
......@@ -177406,6 +177406,7 @@ fn lowerSwitchBr(
177406177406 }
177407177407 if (switch_br.else_body_len > 0) {
177408177408 const else_body = cases_it.elseBody();
177409 const state = try cg.saveState();
177409177410
177410177411 const else_deaths = liveness.deaths.len - 1;
177411177412 for (liveness.deaths[else_deaths]) |operand| try cg.processDeath(operand, .{});