Gate exit 0 (693 regions, MATCH), 344 tests OK, make check exit 0, tracked patch regenerated so
pristine + patch reproduces the working tree.
+4 this commit (worker D): 0x80100334, 0x800FBDC0, 0x800F88F0 (all maspsx=epilogue), 0x80042DD4.
Phase: 602 -> 684 = +82. Milestone 750 was not reached; +66 remains.
TWO TOOL INCIDENTS OF MINE, both reported by workers before I saw them, both repaired:
1. I edited tools/sf3_match in place while four workers verified against it. The new add_argument
block landed between `--fill-epilogue` and its help=, raising IndentationError at line 1129 --
EVERY worker's verification failed for the duration. A verified with a probe copy and re-verified
with the official tool once it parsed; D reported it independently.
2. Reverting an untested transform, my scripted edit DELETED `_LOAD_RA`, the load-delay regex
fill_epilogue needs, breaking maspsx=epilogue for all 21 regions carrying the token. The
whole-binary gate caught it immediately (exit 2, no result line) and it is repaired at the point
of damage.
Guard adopted for every future tool edit: ast.parse immediately after saving, and one atomic write
rather than a scripted multi-step edit. A worker cannot tell a transient tool break from a broken row,
and the cost lands in their context.
ONE DEFERRED ITEM COSTS A BODY: `gp=-` is SINGLE-VALUED per region. D's 0x80102F58 (60 B) needs
D_801221A8/AA/AC registered with gp markers (proven: 60/0 with, 72 without), but A's merged 0x800FFF60
needs those same three ABSENT from the registry because it uses them as SYMBOLS with per-site macro
expansion. Measured: adding the rows breaks A's 140 -> 124; adding them AND giving A three gp=- overrides
restores A to 140/0 -- but the parser refuses with `duplicate override key 'gp'`. The resolution is
proven; only the option key's multiplicity blocks it. Cheapest remaining body in the phase.
The la SYM+N harness transform the developer directed was implemented and REVERTED, because it did not
close its target and an untested transform in the shipped tool is worse than a documented design. Its
mechanism, its guard, where it belongs in the pipeline, and the open question about WHICH STAGE's text
it must rewrite are all in the ledger so it can be resumed without re-deriving.
Also recorded: the gp-rewrite bug worker A found and I fixed (a stale %hi from an unrecorded register
redefinition); the compiler-boundary class (3 rows no vendored cc1 can build); the per-region codegen
flag policy; D's measured tier finding (4/4 with a call or a frame, 0/4 on leaves); and the reading
rules discovered this session, each with at least two instances.
**670 bodies / 680 regions. Phase: 602 -> 670 = +68.**
**+3 bodies, all verified by me from fresh --work dirs at their REAL extents:**
0x80107CCC (76 B, cc1bin=gcc-2.8.1-psx) -- A's row, unlocked by the tool fix below
0x8002D060 (72 B, D) 0x8006FAEC (88 B, D)
And +2 earlier this round: 0x8004D7C8 (220 B, B), 0x8003A9C8 (240 B, B).
**WORKER A FOUND A REAL BUG IN tools/sf3_match AND I FIXED IT.** `rewrite_gp_accesses`'s `_GP_LO`
branch rewrote `lw $2,%lo(SYM)($R)` to `lw $2,%gp_rel(SYM)($gp)` and then `continue`d WITHOUT recording
that the rewrite redefines its destination register. `carrying` kept the stale `%hi`, the register's
next use was scored as an unrewritten use, and the `%hi` was deliberately kept -- so the region came
out exactly 4 bytes long, one instruction.
I reproduced the evidence independently before touching the code, in 0x80107CCC's pre-fix output:
lui $2,%hi(D_801221CC) # high
lw $2,%gp_rel(D_801221CC)($gp)
The same failure the docstring says was fixed for the adjacent-lines case, still live for the
load-whose-result-is-used-later case. One-line fix, A's reasoning and name in the comment, plus why it
stayed invisible: nothing breaks until a gp-marked LOAD feeds something.
Measured: 80/LENGTH-MISMATCH -> 76/0/MATCH. **The tool change was GATED, not trusted**: the pass
touches every gp region, so the full gate was re-run -- c_regions=678, differing_bytes=0, MATCH. That
also answers A, which asked whether the four merged cc1bin rows needed re-verification; the gate is
what proves it and it was green.
**AND WORKER D FOUND THE SAME PASS FROM THE OPPOSITE DIRECTION** on 0x800FFBBC: cc1 2.8.1 puts a safe
`lui $2,%hi(...)` in a branch delay slot, the rewrite folds the hi/lo pair to gp-relative, the lui
DISAPPEARS and the store slides into the delay slot (48 -> 44). So A's case is the rewrite failing to
fire and D's is the rewrite firing and changing a schedule -- two faces of one pass, on two rows, found
by two workers who could not see each other's row. D's framing is the open item: a maspsx mode that
re-derives the delay slot after the gp-relative rewrite would likely close a class.
**cc1bin's measured boundary, and a correction to my own guidance.** B swept the compilers: 2.5.7 /
2.6.0 / 2.6.3 / 2.7.2 / 2.7.2-cdk / 2.7.2-psx give a MERGED epilogue; 2.8.0-psx / 2.8.1-psx give
SEPARATE jr $31 per return. So return merging is a 2.7.2-family behaviour. BUT 2.8.x also changes the
GLOBAL ACCESS FORM (explicit lui %hi / lw %lo pair instead of the symbolic load maspsx turns into
lw v0,2080(gp)). **The lever moves two axes at once and is not free** -- which corrects what I told A,
B and D when routing the multi-exit rows.
**0x80107D7C sits BETWEEN the compilers and is a genuine open question.** B: default 112, 2.8.1 104,
target 108. I swept all TEN vendored builds because B's table listed eight: only 2.7.2-cdk produces 108
bytes, and it is 30 bytes off in content. 2.91.66 and 2.95.2 give 100. So the length is reachable and
the content is not, on any vendored compiler.
**Two corrections of record, both mine:** I guessed extents instead of reading
config/function_extents.tsv (testing A's 76-byte row against an 80-byte extent and reporting
LENGTH-MISMATCH from a correct candidate); and I told three workers cc1bin was a clean lever for the
multi-exit rows when B's sweep shows it moves two axes.
**Ruling on A's per-region codegen flag request (0x800AB504): (b) class-bound, with the diagnosis
kept** -- because `-fno-strength-reduce` gives 152 against a 148 target. A flag that closes a row is a
lever; one that moves a row 16 bytes closer to a different number is a diagnosis. But the PRINCIPLE is
recorded for the next such row: a codegen flag is admissible on the same terms as cc1bin, i.e. a named
mechanism in the bytes, and A has one (address normalisation creating a second loop-carried pointer).
**D: the indexed and pointer loop forms COEXIST and neither carries across rows.** 0x8002D060 matches
only as an INDEXED loop; 0x80107B40 wants the pointer form. A direct refutation of pattern-carrying
from the worker with the most reason to trust a pattern. Also: the both-sides-volatile rule TRANSFERS
(0x8006FAEC), with the narrowing measured (only interleaved accesses need it); and READ the displacement
and compute the symbol rather than inferring it from an adjacent symbol's name (gp+0xBA4 -> 0x801224DC).
**Charter note: `--cc1-flag=X` REPLACES the default `-quiet -O2 -G0` set**, so a diagnosis run must
pass all four explicitly. A's first -fthread-jumps probe read 200 B purely because -O2 was dropped.
MERGE 23: +2 bodies from worker D's un-attempted band, both re-verified from fresh --work dirs:
0x800582AC (64 B) and 0x800A82D0 (64 B). Gate c_regions=676, differing_bytes=0, MATCH.
DISPATCH CORRECTION, and it came from checking a claim rather than forwarding it. D reported three
multi-exit rows as unclosable because 'my multi-return probes share ONE exit under all ten cc1 builds'.
Measured from the binary: ALL SEVEN unregistered multi-exit rows are >=2 jr $31, which is the gate's
precondition for naming an alternative cc1 -- so the restriction PERMITS the lever on every one, with
four merged rows as precedent.
And C's measured row refutes the probe conclusion directly: 0x801008DC is 3 exits and the default gives
the correct 88 bytes with 58 DIFFERING bytes because it merges all three returns, while
cc1bin=gcc-2.8.1-psx gives 88/0/MATCH. The merge is SHAPE-dependent, and a synthetic probe speaks only
for the shape it probes. I made exactly this error earlier in the phase with a probe-dependent
mechanism written into tools/sf3_match.
Rows routed: A gets 0x80107CCC (3 exits, A has the diagnosis), B gets 0x800FF6DC / 0x80100998 /
0x80107D7C, D gets 0x800FFBBC.
Also recorded: D's self-caught harness hazard -- its run helper leaves the LAST variant on disk, so its
first verification of 0x800A82D0 ran against the wrong variant and report.tsv's md5 described it. D
re-verified from a fresh directory and made the re-write explicit in its procedure. This is the failure
mode that would produce a FALSE MATCH CLAIM rather than a missed one, and it is invisible from outside
because the report's own md5 agrees with the wrong file.