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.