From d81bdd8ab9092b844c974d0ab6dfe150cbf18f8d Mon Sep 17 00:00:00 2001 From: xtex Date: Wed, 2 Sep 2026 13:23:12 +0800 Subject: [PATCH] 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 --- src/codegen/x86_64/CodeGen.zig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/codegen/x86_64/CodeGen.zig b/src/codegen/x86_64/CodeGen.zig index 97865d02b6f6247d285cee01f1abe03f42d908b7..b2335f3c7dfff9213e7af715123a9151dd0b0721 100644 --- a/src/codegen/x86_64/CodeGen.zig +++ b/src/codegen/x86_64/CodeGen.zig @@ -177120,8 +177120,6 @@ fn lowerSwitchBr( var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), cg.gpa); const allocator = bfa.allocator(); - const state = try cg.saveState(); - const liveness = try cg.liveness.getSwitchBr(allocator, inst, switch_br.cases_len + 1); defer allocator.free(liveness.deaths); @@ -177232,6 +177230,7 @@ fn lowerSwitchBr( } }; var cases_it = switch_br.iterateCases(); + const state = try cg.saveState(); while (cases_it.next()) |case| { { const table = cg.mir_table.items[table_start..][0..table_len]; @@ -177388,6 +177387,7 @@ fn lowerSwitchBr( // The jump to skip this case if the conditions all failed. const skip_case_reloc = try cg.asmJmpReloc(undefined); + const state = try cg.saveState(); for (liveness.deaths[case.idx]) |operand| try cg.processDeath(operand, .{}); @@ -177406,6 +177406,7 @@ fn lowerSwitchBr( } if (switch_br.else_body_len > 0) { const else_body = cases_it.elseBody(); + const state = try cg.saveState(); const else_deaths = liveness.deaths.len - 1; for (liveness.deaths[else_deaths]) |operand| try cg.processDeath(operand, .{}); -- 2.54.0