Files
BFM-decomp/cookbook/C0407.md
T

1.3 KiB

§366 ★★ — group_case_nodes MERGES STACKED CONSECUTIVE CASE LABELS: GIVE EVERY CASE ITS OWN BODY (P31 S68; ov_SC01_001/func_8017EC28, first-try MATCH 360/360, 96/96 relocs audited)

gcc-2.7.2 group_case_nodes (stmt.c:5281, from expand_end_case:4752) merges CONSECUTIVE case values into ONE range node whenever next_real_insn(label_rtx(code_label)) is identical — i.e. whenever labels are STACKED:

case 5: case 6: case 7:  body;        /* -> ONE node, shrinking the balanced tree */

Three stacked consecutive runs ({5,6,7}, {0x53A,0x53B}, {0x57A,0x57B}) = 4 fewer case nodes, which was exactly the observed -25 LENGTH-DRIFT.

The fix: give EVERY case its own DUPLICATED body + break so no two labels share a next_real_insn, then let cross_jump fold them back — ordering arms so each family's fold lands after its LAST contributing arm (§298). That reproduced the target's .L…000 -> .L…010, .L…090 -> .L…098 and .L…0DC -> .L…0E4 fall-throughs.

Diagnostic: an unexplained LENGTH drift on a switch, equal to a small number of case nodes, points at group_case_nodes before anything else. Same "spell it long, let a later pass re-merge" family as §360/§361 — but here cross_jump is the intended merger, not an accident.