4.9 KiB
§316 — A GUARD CHAIN THAT GATES A SUCCESS BLOCK ROUTES ITS FAILING GUARDS TO A LABEL BEFORE THE FLAG TEST, NOT TO THE EPILOGUE: THE RESIDUAL IS IMM-OFFSET-ONLY AT AN EXACTLY EQUAL INSTRUCTION COUNT (P31 S66; byte-proven func_80180284)
(BOUNDS §225-3, whose early-return ladder is the winning spelling only when the chain ends in a bare return C == D; with no success block — with a success block the same ladder is what fails here. Instantiates §225-1's "failure edges need explicit gotos landing mid-flow" for a flag test rather than a shared call. Generalises §176-F row 3 / its S62 T4 addendum from one branch to N. NOT §195-E: the named-flag-across-a-join axis is already satisfied in both the failing and the matching draft. NOT §195-N: that law's chain has no success block and its own BOUND 2 kills it when the returned constant is not 1, which is this function's case.)
THE DIAGNOSTIC TELL. match_one reports klass == "IMM-OFFSET", bucket == "structural", nins_mine == nins_tgt exactly, and every residual word is one of the early-guard branches carrying the same constant displacement delta — sig IMM-OFFSET/-9, n=3, kinds:{"imm":3}. The instruction sequence and count are already 100% right; only the beqz/bne guard-fail targets are off, by a fixed word count equal to the size of the flag-test-plus-success block your branches are jumping over. A shared delta across N branches is not a scheduling nuance and not a dropped edge — it is one wrong destination shared by N edges. Count the words between the target's guard-branch label and your own before touching polarity, pins or statement order.
THE MECHANISM (as far as it is demonstrated). Written as N independent if (guard_fail) return 0; statements, cross-jump/tail-merge collapses the N return 0 tails to one, so the count comes out right — but every guard branch lands on the function's outer epilogue, past the whole flag-test/success block. The real source instead converges all N failing guards on a label sitting immediately before the last chain term's flag test, with $v0 already zeroed from the failed comparison, so the flag-test and branch machinery is reused rather than bypassed. The last chain term must stay its own one-line statement (r = last_cmp;); folding it back into the &&/if condition re-triggers the §195-N-family value-form tax (see the caveat below). Each guard edge must also explicitly re-zero r — leaving it uninitialised on one path is a semantic bug, not a dial, and regressed this function from closeness 3 to 50.
THE C SHAPE.
/* closeness=3, IMM-OFFSET/-9, nins 50 == 50 — WRONG: every guard branch
lands past the flag test, at the outer epilogue */
if (guard1_fail) return 0;
if (guard2_fail) return 0;
if (guard3_fail) return 0;
r = last_cmp;
if (r) { success_stuff(); return x; }
return 0;
/* closeness=0, MATCH, nins 50 — guards converge on a label BEFORE the flag
test, each re-zeroing r first (this is func_80180284 verbatim) */
if (guard1_fail) { r = 0; goto chain_fail; }
if (guard2_fail) { r = 0; goto chain_fail; }
if (guard3_fail) { r = 0; goto chain_fail; }
r = last_cmp; /* last chain term: its OWN statement, never folded into && */
chain_fail:
if (r) { success_stuff(); return x; }
return 0;
BYTE EVIDENCE. func_80180284 (ov_SC04_019, 50 ins, MATCH, banked at src/ov_SC04_019/ov_SC04_019_jr_8017AE2C.c:6064-6094 — three r = 0; goto chain_fail; guards with chain_fail: immediately above if (r)). match_one --json trajectory across fifteen drafts: 53→29→44→19→53→19→19→19→53→19→18→3 (draft11, the early-return 0 ladder: {"klass":"IMM-OFFSET","closeness":3,"nins_mine":50,"nins_tgt":50,"sig":"IMM-OFFSET/-9","detail":{"delta":-9,"n":3,"kinds":{"imm":3}}}) →18 (draft12, last term folded back into &&, LENGTH-DRIFT/+1) →50 (draft13, goto shape but r uninitialised on one path) →22 (draft14, nested if/else with r = 0 in each else) →0 (draft15, {"status":"match","closeness":0,"nins":50,"residual":[]}). Note: the same vram in ov_SC03_102 is an unrelated one-line body — cite the ov_SC04_019 definition.
SCOPE, stated honestly. One function, five spellings, one overlay. The prescription is byte-proven; the gcc internals are not — no jump.c/cse.c/reorg.c line was traced for which pass fixes the displacement or why the shared label must precede the flag test, and that half is inferred from the residual shape alone. The draft12 +1 j observation is weaker than the rest: draft12 moved from the goto shape back to && and re-inlined r (closeness 3 → 18), so it is not a single-axis A/B, and it sits outside §195-N's stated preconditions (no success block; returned constant must be 1) — it is evidence that §195-N's BOUND 2 may be over-broad, not a confirmed instance of §195-N. Re-measure both on the first out-of-TU instance before treating either as settled.