From 77dc52c633e155c5da75eddf68312778febe529a Mon Sep 17 00:00:00 2001 From: Drew T <50529377+Druthulu@users.noreply.github.com> Date: Thu, 3 Sep 2026 16:20:59 -0600 Subject: [PATCH] =?UTF-8?q?docs(cookbook):=20=C2=A7474=20=E2=80=94=20a=20P?= =?UTF-8?q?ROVED=20-O0=20floor=20from=20split=5Ftree=20+=20stupid.c?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From the S76 func_80011380 agent, which upgraded an empirical closeness-6 plateau to a floor proved from the gcc sources in tools/reference/. The target needs MULT(MULT(i,2),2) unmerged, but fold-const.c:882 split_tree decomposes any MULT whose op1 is TREE_CONSTANT — all 20 spellings measured collapse to one sll 2, and STRIP_NOPS eats NON_LVALUE_EXPR so the usual |0 +0 *1 &~0 ^0 >>0 shields cannot protect it. Both escapes cost an instruction, each for a named reason: a stmt-expr gives the exact 5-insn RTL but its BLOCK_END note breaks the adjacency that stupid.c:497-508 needs for a copy to conflict with its source, so the copy self-coalesces and final.c deletes it; and (t = i*2)*2 with register s32 t reaches exact length and shape but expand_decl's zero-byte (use) brackets make t the longest interval, seizing $v0 and rotating the register ring. Clinching fact that the target has no variable there: its 4th insn sll $v1,$a0,1 reads $a0, not insn 2's dest. Bonus: expand_binop allocates the PLUS dest before force_reg'ing the symbol, so the symbol pseudo loses stupid_reg_compare's tie-break — that is the la-on-$a0 colour. Recorded as the TEMPLATE for a wall claim: name the pass, cite file and line, measure each escape, and give the byte fact ruling out the alternative. A wall asserted without that is a belief (§473). --- docs/matching-cookbook.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/docs/matching-cookbook.md b/docs/matching-cookbook.md index 66cada824..0527a2632 100644 --- a/docs/matching-cookbook.md +++ b/docs/matching-cookbook.md @@ -35540,3 +35540,40 @@ belief than a compiler limit — re-probe before honouring one.** diamond-merge label flushes `cse2`, and every zero-byte flush tried killed either the tail cross-jump or the fp loop-invariant hoist; plus a 2×5-instruction mode-copy allocation in the OTZ clamp and the `$a0`/`$s7` prologue schedule.)* + +#### §474 — A *PROVED* C-LEVEL FLOOR: `split_tree` + `stupid.c` (-O0), from `main:func_80011380` + +**Source: the S76 agent, which upgraded an empirical closeness-6 plateau to a floor PROVED from +`tools/reference/` gcc sources.** The counterweight to §473 and friends: most recorded walls in this +project have been stale, but **this one is real and now has a proof**, so it should never be +re-ground. + +**The demand.** The target needs `MULT(MULT(i,2),2)` left **unmerged**. + +**Why no C spelling delivers it.** `fold-const.c:882` `split_tree` decomposes ANY `MULT` whose `op1` +is `TREE_CONSTANT`. All 20 anonymous / identity / array spellings measured collapse to a single +`sll 2` (190 ins), and **`STRIP_NOPS` eats `NON_LVALUE_EXPR`**, so the usual shields — `|0`, `+0`, +`*1`, `&~0`, `^0`, `>>0` — cannot protect the inner multiply. + +**Why the two escapes each cost an instruction.** +* A **statement-expression** produces the EXACT 5-instruction RTL (confirmed with `cc1 -dr`) — but + its `BLOCK_END` note lands between the `sll` and the next copy. `stupid.c:497-508` computes + `dead = max(last_use, born+2)` with `occ = [born, dead-1]`, so a copy conflicts with its source + **only when immediately adjacent**; the note breaks the adjacency, the copy self-coalesces, and + `final.c` deletes it (191). +* `(t = i*2) * 2` with `register s32 t` is a genuine fold blocker and reaches **exact length 192 with + the exact instruction shape** (closeness 12, the best new construct) — but `expand_decl` / + `use_variable` emit zero-byte `(use)` brackets that make `t` the longest live interval, so it + seizes `$v0` and rotates the whole `{v0,v1,a0,a1,a2}` ring one step. + +**The clinching proof that the target has NO variable there:** its 4th instruction `sll $v1,$a0,1` +reads **`$a0`**, not insn 2's destination. A variable would have to be the deleted move, and `t` can +never be. Hard-register pins `$2..$5/$8/$9` all keep the copy (193); a stack `t` costs 194. + +**Bonus law, same oracle — the `la`-on-`$a0` colour.** `expand_binop` allocates the `PLUS` +destination **before** `force_reg`'ing the symbol, so the symbol's pseudo gets the higher regno and +loses `stupid_reg_compare`'s tie-break. That explains a -O0 register colour that looks arbitrary. + +**Use this section as the template for a wall claim:** name the pass, cite the file and line, show +the measured cost of each escape, and give the byte-level fact that rules out the alternative. A wall +asserted without that is a belief (see §473).