phase11: merge 4 — 494 bodies / 503 regions, THIRD body above the old ceiling (new max 264 B)

Worker D's 0x800308C4 (264 B) MATCHES, verified independently and gated on the whole
binary before promotion. Three bodies now sit above the old 244 B ceiling
(248/248/264 B) from two independent workers, so the dispatch-artefact verdict is
settled by result.

COOKBOOK 59 EXTENDED WITH A NEW MECHANISM. D's first attempt was 8 words from a match
and all eight were the FRAME; 56 of 64 words were already byte-identical including
every call site, delay slot and register. The missing 8 bytes are an UNREFERENCED
ARRAY LOCAL, and the mechanism is measured across five spellings: cc1 allocates stack
space for an unreferenced ARRAY local but NOT for an unreferenced SCALAR local
(`int pad0, pad1;` gives no home; `int pad[2]` and `short pad[4]` both match). The 8
bytes are size-load-bearing and content-free -- a limit of the reconstruction, not a
recovered fact, recorded as such in the file header.

AMENDED RULE: when the residual IS the frame, vary the local aggregate's declaration
in THREE directions -- element type, row stride, and total size. Instance 1
(0x8009F6A0) needed the row stride; instance 2 (0x800308C4) needed the total size.
This commit is contained in:
Christopher Williams
2026-09-24 09:00:06 -04:00
parent 7d7f41fbaa
commit e7caec4443
2 changed files with 25 additions and 0 deletions
+1
View File
@@ -128,6 +128,7 @@
0x800301FC 0x8003022C src/func_800301FC.c
0x80030284 0x800302DC src/func_80030284.c
0x80030358 0x80030390 src/func_80030358.c
0x800308C4 0x800309CC src/func_800308C4.c
0x80031F2C 0x80031F78 src/func_80031F2C.c
0x80031F78 0x80031FC4 src/func_80031F78.c
0x800321EC 0x800321F8 src/func_800321EC.c
1 # Code-region registry: one C region per matched function.
128 0x800301FC
129 0x80030284
130 0x80030358
131 0x800308C4
132 0x80031F2C
133 0x80031F78
134 0x800321EC
+24
View File
@@ -970,6 +970,30 @@ ADJUSTMENT and every sp-relative offset ⇒ suspect a local aggregate's row stri
control flow.** The element type is the other half of the lever — `short` locals let cc1 drop the sign
extension, `int` locals keep it.
**PHASE 11 INSTANCE 2 — AN UNREFERENCED ARRAY LOCAL IS SIZE-LOAD-BEARING AND CONTENT-FREE.** `0x800308C4`
(264 B, a new corpus maximum) came out **8 words from a match, and every one of the eight was the frame** —
the `addiu sp,sp,-96` / `sw ra,88(sp)` / `sw s1,84(sp)` / `sw s0,80(sp)` prologue and its mirror epilogue,
with **56 of 64 words already byte-identical** including every call site, delay slot and register. The
missing 8 bytes are an **unreferenced array local**, and the mechanism is measured:
| trailing declaration | vars | frame | result |
|---|---|---|---|
| (none) | 56 | 88 | DIFF, 8 words |
| `int pad0, pad1;` (2 unreferenced **scalars**) | 56 | 88 | DIFF, 8 words — **cc1 gives unreferenced scalars no home** |
| `short t[12]` (one 24-byte array) | 56 | 88 | DIFF, 8 words |
| `int pad[2]` (unreferenced 8-byte **array**) | 64 | **96** | **MATCH** |
| `short pad[4]` (unreferenced 8-byte **array**) | 64 | **96** | **MATCH** |
**cc1 allocates stack space for an unreferenced ARRAY local but not for an unreferenced SCALAR local**, and
the original declares one more array local than its emitted code touches. The 8 bytes are
**size-load-bearing and content-free** — any 8-byte array reproduces them. That is a limit of the
reconstruction, not a recovered fact, and it must be recorded as such in the file header.
**AMENDED RULE: when the residual IS the frame, vary the local aggregate's declaration in THREE directions
— element type, row stride, AND total size.** Instance 1 (`0x8009F6A0`) needed the **row stride**
(`int t[3][4]` not `int t[9]`); instance 2 (`0x800308C4`) needed the **total size** (an unreferenced 8-byte
array). Two instances, two different directions, same diagnostic.
### 60. A new trapped class: compiler-generated division checks (`div` + `break`)
`break` **never** appears without `div` and `div` **never** appears without `break` — 75 worklist rows,