phase11: merge 60 + cookbook 181-182 — 601 bodies / 610 regions

Worker F's 0x8002622C (44 B) — A RECORDED NEGATIVE OVERTURNED, with a new class.

The old record said 'cc1 folds it, unreachable' and tried FOUR ALGEBRAIC re-spellings. All four
were doomed: the fold is at RTL combine, not in the front end, so no re-spelling can avoid it.
Only LIVENESS can. Same body with 'return 0' is 32 B LENGTH-MISMATCH; with 'return n' (the
difference live past the addition) it is 44/0/MATCH. Diagnostic that proves the pass: cc1 -da
shows the minus present in the .flow dump and gone in the .combine dump, while cse/cse2/jump/
loop/sched/sched2 all still contain it.

181: when an original keeps an arithmetically-cancelling pair (subu+addu, x-c+c), the intermediate
is LIVE PAST the second operation — find the later reader.

182: a negative with a NAMED mechanism is overturnable; one without is not. 'cc1 folds it' is not
a classification; 'RTL combine cancels it, and algebraic re-spelling cannot reach combine' is,
and it immediately implies the liveness lever.
This commit is contained in:
Christopher Williams
2026-09-24 11:42:17 -04:00
parent 3519afe441
commit b0ed17d494
4 changed files with 1090 additions and 990 deletions
+989 -990
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -90,6 +90,7 @@
0x80025ADC 0x80025B64 src/func_80025ADC.c
0x80026180 0x800261C0 src/func_80026180.c
0x800261C0 0x8002622C src/func_800261C0.c
0x8002622C 0x80026258 src/func_8002622C.c
0x80026258 0x80026264 src/func_80026258.c
0x80026264 0x80026274 src/func_80026264.c
0x80026274 0x800262E0 src/func_80026274.c
1 # Code-region registry: one C region per matched function.
90 0x80025ADC
91 0x80026180
92 0x800261C0
93 0x8002622C
94 0x80026258
95 0x80026264
96 0x80026274
+41
View File
@@ -2928,3 +2928,44 @@ token had been applied by shape.** The cheap read, and the one to remember:
> **"4 bytes SHORT with the token on" means the token was unnecessary** — that is exactly how
> `0x80091674` and `0x801080B8` present.
### 181. *** AN ARITHMETICALLY-CANCELLING PAIR MEANS THE INTERMEDIATE IS LIVE PAST IT ***
**Worker F overturned a recorded negative with this, and it is a new class.**
`0x8002622C` was in `near_match_negatives.tsv` — the earlier record said *"cc1 folds it, unreachable"*
and tried **four algebraic re-spellings**. All four were doomed: **the fold is not in the front end,
it is at RTL combine, so no re-spelling can ever avoid it. Only LIVENESS can.**
| spelling | result |
|---|---|
| same body with `return 0;` | **32 B LENGTH-MISMATCH** — folded to one `la` and four stores of `$4` |
| with **`return n;`** (the difference live past the addition) | **44 B / 0 differing / MATCH** |
**Diagnostic that PROVES the pass:** `cc1 -da` — the `minus` is present in the **`.flow` dump** and
**gone in the `.combine` dump**; `cse`, `cse2`, `jump`, `loop`, `sched`, `sched2` all still contain it.
> **When an original keeps an arithmetically-cancelling pair (`subu`+`addu`, `x − c + c`, a redundant
> recomputation), the intermediate is LIVE PAST the second operation — find the later reader.** Here
> it is the function's return value, and it costs **zero** instructions because the difference's home
> is already the return register `v0`.
**Two corollaries from the same row:** `D_8015E978` must be a **symbol**
(`extern char D_8015E978[];`) or the `la` becomes `lui`+`ori`; and the entry `move v0,a0` exists
because `a0` stays live (stored to `D_80121B20`), so the source's `n = a0` cannot coalesce.
**And the general lesson about NEGATIVES:** a recorded negative is a record of **attempts**, not of
impossibility. **This row's four recorded spellings were all algebraic; the answer was in a different
dimension.** Worker F took it because the record was old enough to predate the current toolset — and
the tools had nothing to do with it. **The lever class had simply never been tried.**
### 182. A negative with a NAMED mechanism is overturnable; one without is not
`0x8002622C`'s record said *"cc1 folds it"* — **a mechanism claim, and it was half right**: cc1 does
fold it, but the record concluded *unreachable* from that, when the correct conclusion is *only
liveness can prevent it*. **Worker F's four attempts failed for the same reason and nobody noticed,
because they were all in the same dimension.**
> **When you classify a row unreachable, state WHICH PASS does the damage and WHAT DIMENSION you
> exhausted.** "cc1 folds it" is not a classification; "RTL combine cancels it, and algebraic
> re-spelling cannot reach combine" is — and it immediately implies the liveness lever.
+59
View File
@@ -0,0 +1,59 @@
/*
* func_8002622C — 44 bytes at 0x8002622C..0x80026258
*
* Initialises the four `gp`-relative arena globals from the arena base passed in
* `a0`, and returns the arena's distance from the fixed data address D_8015E978.
*
* The observed instructions are:
* move v0,a0 n = a0 (n cannot coalesce with a0)
* lui v1,0x8016 \
* addiu v1,v1,-5768 / v1 = D_8015E978 (a SYMBOL: `la`, not `li`)
* sw v0,488(gp) D_80121B20 = n
* subu v0,v0,v1 n = n - D_8015E978
* sw v1,476(gp) D_80121B14 = D_8015E978
* addu v1,v0,v1 x = n + D_8015E978
* sw v1,480(gp) D_80121B18 = x
* sw v1,484(gp) D_80121B1C = x
* jr ra return n;
*
* THE `subu`/`addu` PAIR IS KEPT ONLY BECAUSE THE DIFFERENCE IS RETURNED.
* `(a0 - K) + K` is cancelled by combine's dead-register substitution, and this
* row is on the recorded-negative list (`config/near_match_negatives.tsv` line
* 47) for exactly that reason. The lever that was missing is LIVENESS, not
* algebra: if the difference's live range ends at the addition, combine
* substitutes its definition and folds the pair away (probe H3, `return 0;`,
* 32 B), while keeping it alive past the addition — here by returning it —
* blocks the substitution and reproduces the original 44 B. Diagnostic: with
* cc1 `-da` the `minus` is present in the `.flow` dump and gone in `.combine`.
* The fold is at the RTL level (combine), NOT in the front end, so no
* algebraic re-spelling of the source can avoid it — only liveness can.
*
* The `move v0,a0` is the source's `n = a0`: `a0` stays live (it is stored to
* D_80121B20), so the copy cannot coalesce, and `n`'s home is the return
* register v0.
*
* D_8015E978 MUST be a symbol reference: written as a literal the address
* materialises as `lui`+`ori` instead of `lui`+`addiu`. The four globals are
* registered `gp` in `config/symbols.tsv`, giving the `%gp_rel` stores.
*
* LIMITS: the name, the return type, the widths of the four globals and the
* meaning of the difference are hypotheses reconstructed from the disassembly;
* only the compiled bytes are evidence.
*/
extern int D_80121B14;
extern int D_80121B18;
extern int D_80121B1C;
extern int D_80121B20;
extern char D_8015E978[];
int func_8002622C(int a0) {
int n = a0;
D_80121B20 = n;
D_80121B14 = (int)D_8015E978;
n = n - (int)D_8015E978;
D_80121B18 = n + (int)D_8015E978;
D_80121B1C = n + (int)D_8015E978;
return n;
}