4.4 KiB
§30 — Fable5Max cracks §20/§10 "unsteerable" from the gcc SOURCE: store-vs-load is a /s aliasing flag, the def-side wall has a macro escape, + the birthing-boost (Phase 23, byte-proven on giant func_8014EE14 248 ins ×134)
A single Fable5Max agent (an Agent with model: fable, given the target asm + tools/ghidra_c/ + this cookbook + the match_one→gate_stage loop) matched a 248-ins reach-134 GIANT on the §20/§10 store-vs-load wall — the class 22 phases of Opus/GLM called "CONFIRMED unsteerable" — by reading the actual gcc-2.7.2 source (tools/reference/gcc-papermario) with -da RTL dumps. It banked ×134 (leaf MATCH (248 ins); whole-binary banked:1; check-all 136/136; dedup-check 1780/0). The §29 "not a bigger model" verdict is corrected: a frontier model that goes to the compiler INTERNALS is a wall-breaker for the codegen classes. Three byte-proven idioms:
- STORE-vs-LOAD IS A DETERMINISTIC ALIASING FLAG, NOT A SCHEDULER TIE-BREAK (revises §10/§20 "unsteerable"). gcc-2.7.2
expr.csetsMEM_IN_STRUCT_P(/s) only when a load's address is a member/aggregate ref or was "computed by addition" (PLUS_EXPR). The front end foldsp[0]→*p, so zero-offset / bare-deref loads never get/s→ they carry a hard true-dependence on an aliasing fixed-symbol store (D_xxx = 0) and get stuck below it; offset/member loads have/sand hoist freely. So the store-vs-load "coin-flip" is a binary flag you SET from C:- Grant
/s(make the load hoist over the store): write it as a struct-member ref →((struct { s32 field; } *)p)->field. Use an ANONYMOUS struct in the cast —dedup_propagate(line ~366) rejects inline named structs, so anonymous keeps the/sflag AND stays propagatable ×134. - Deny
/s(keep the load below the store, e.g. a separate reload the target shows): keep it a bare*p/p[0]. (CSE's fixed-scalar-store invalidation only kills non-/sentries — that's what forces the target's separate reload.) - The tell in any diff: a zero-offset pointer load stuck on one side of a fixed-symbol store while offset loads float. Re-test candidates:
func_8014F2E0,func_80150528,func_8014EA4C(close=6), and every §10/§20 "store-vs-load unsteerable" backlog verdict.
- Grant
- THE DEF-SIDE RETURN-TYPE WALL HAS A MACRO ESCAPE (extends §29). When a matching def must return
s32(avoidreturn DCEs a computed local → frame shrinks → no match) but the only conflicting caller-decl is a sharedDEFINE_func_*macro that DISCARDS the return: widen that macro'sextern void func_X(...)→extern s32 func_X(...). It's byte-neutral for the caller (the return is discarded — verifiedcheck-all 136/136fleet-wide). §29 said "no escape" because a bareINCLUDE_ASMstub declares no C symbol — but a macro DOES declare the symbol via itsexternline, so there is one. (The narrow-scalar-param-by-value wall from §29 still stands — this dissolves only the return-type conflict.) - THE "BIRTHING-BOOST" PROLOGUE-ORDER LEVER.
sched.c:adjust_priority(pre-reload only) boosts to max priority any insn whose dest reg is set exactly once in the fn (birthing_insn_p:REG_N_SETS==1); sched1 schedules each bb backward, so a boosted insn is picked early = placed late. Single-set param copies (s0=a0) then sink below multi-set const inits (s6=0/s5=8, reassigned in a switch → never boosted). Fix: one zero-byte NON-volatile re-tie__asm__("" : "=r"(x) : "0"(x))on the param, placed in a LATER basic block (after the switch). It counts as a 2nd SET (boost dead), emits nothing, adds no bb0 edges → all inits tie and the LUID/source-order tie-break restores params-first. Generalizes to any wrong prologue/init ORDER between single-set and multi-set defs.
Meta-lesson (feeds effort-map / R17): the "idiom well is dry / wall is intrinsic" verdict (T10.8/T10.9, §29) was model-relative — true for GLM and the local 7B, false for a frontier model that reads the gcc-2.7.2 source. The wall-breaker recipe: Agent(model:fable) + tools/reference/gcc-papermario (RTL -da dumps) + this toolkit + the match_one/gate_stage loop, on ONE giant at a time. Cost ≈ 375k agent-tokens / giant across the leaf-crack + whole-binary integration (2 rounds). NB: match_one (isolated) masks in-TU declaration conflicts — always finish on the whole-binary gate_stage (the §20 stale-.o trap can fake a pass; force a clean compile).