kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

O1 code-quality patterns: the post-W1 disassembly catalog

A curated catalog of the residual -O1 vs clang -O1 code-quality gaps, from a per-file disassembly audit of the ecosystem corpus after the entire O1.md §3 worklist (W1–W10) landed (2026-06-16, aggregate __TEXT ≈ 1.09× clang). This is the successor to that worklist: it identifies what remains, ranks the linear/no-SSA wins still on the table, and cleanly separates them from the gaps that genuinely require the parked O2 SSA mid-end.

Update (2026-06-16): all of §2 (L1–L10) is landed. Implemented in parallel (worktree-isolated agents) and merged gated. Aggregate __TEXT 1.09× → 1.059× clang (lvm 2.86× → 2.57× via L1; yyjson 0.86× → 0.80× via L6/L4/L2; sqlite 1.11× → 1.09×; lparser 1.07× → 1.04× via L9; tinyexpr via L10). Per-item: L1 store→load forwarding (pass_combine.c, lvm −9.95%), L2 cset→cmp_branch fusion (same-block subset; cross-block stays O2), L3 widen aa_set_bytes zero-init (aa64/native.c, cjson −5.4%), L4 double-cset drop, L5 confirmed already-subsumed by try_substitute/try_ret_retarget (no unsound new fold; the scratch-source residual is a miscompile, left out), L6 sxt-after-load drop (yyjson −5.45%), L7 shift-into-ALU + L8 sxtw-index-into-addressing (Operand riders, aa64-only; x64/rv64 capability-gated off), L9 const div/mul fold (pass_simplify.c, lparser udiv 22→0), L10 frameless-leaf elision. L9 also surfaced + got fixed a latent volatile-load miscompile (a volatile load of a register-resident local was served from the value-residency fast path with no observable memory access emitted; fixed in src/cg/memory.c). Gates: test-opt (18 guards) + test-toy 1392/0 + ecosystem 28/0 + smoke-x64/rv64 3/0 + test-cg-api 289/289. The §3 (SSA/O2) and §4 (not-a-deficiency) findings below stand.

Read O1.md first — especially §3 (the landed worklist), §4 (the SSA/O2 out-of-scope list), and §5 (already-landed). Read OPT.md §3 for the O1 pipeline and pass inventory. Every "linear" claim here is checked against those.


1. Methodology

Harness. scripts/o1_quality.sh builds the per-file kit (.k.o) and clang (.c.o) objects into build/o1_quality/; disassemble with ./build/release/kit objdump -d NAME.k.o. Per-file ratio = kit __TEXT ÷ clang __TEXT (size -m). Instruction counts are real instruction lines (objdump format is addr:\t bytes \t mnemonic operands — the mnemonic is after the second tab; a naive grep ':\t\w+' matches the byte column and is wrong).

Corpus and current standings (kit / clang __TEXT, all aarch64/Darwin -O1, release kit):

file kit/clang note
lz4 0.38× clang unrolls/inlines → clang bigger (NOT a kit gap)
yyjson 0.86× kit smaller (clang inlines far more)
lapi 0.83× kit smaller
tinyexpr 0.96× ~par
lparser 1.07× ~par; the SIZE_MAX/udiv guard pushes it over
cjson 1.31× aggregate/array zero-init dominates
miniz 1.67× csel + frame traffic in the deflate loops
sqlite 1.11× frame traffic + bit-tests + addr folds
lvm 2.86× the lua interpreter loop — still the worst

W1.1 is confirmed landed in these objects: sub xN,x29,#k spill-address recomputes are 0 in lvm (was 8,774) and sqlite (was 35,360); every spill slot is a one-instruction positive ldr/str [x29,#k]. So the residual gap is no longer spill addressing — it is the spilling itself (frame round-trips that a real RA would not emit) plus a family of local peepholes the no-SSA O1 still misses.

Rubric. Each pattern is graded LINEAR (a same-block / per-instruction forward peephole, no SSA, no superlinear axis) · NEEDS-SSA-O2 (wants GVN/DSE/LICM/IV or a cross-block register allocator) · NOT-A-DEFICIENCY (clang bigger via inlining/ unrolling, or kit already smaller). Linearity verdicts and host-pass claims were spot-checked against the live passes (pass_combine.c:1914 compact rule, aa_set_bytes at aa64/native.c:2577, aa_add_lsl/aa_ldst_regoff emitters).

Spot-checks performed (all reproduced against the current build/o1_quality/ objects): lvm store→reload-different-register (1495 adjacent + 1962 within-4), mov wN,wM 330 vs clang 5; cjson strb 338 with a 64-long consecutive run; yyjson double-cset 573 triples and cset→cbnz 438. No high-impact pattern was dropped on spot-check (one was downgraded — see §4).


2. Linear / n-log-n O1 opportunities

The actionable shortlist, ranked by (impact × confidence × cross-file breadth). This is the section that matters.

L1 — Store-to-load forwarding across a register mismatch ★ highest leverage

The gap. After a spilled def is homed (str rX,[slot]) the O1 reload at the next use targets a fresh rotating scratch (ldr rY,[slot], rY != rX), so the value round-trips through memory even though rX still holds it. The existing adjacent compaction (opt_combine_compact_block, pass_combine.c:1934) collapses the str;ldr pair only when same_reg_operand(store.src, load.dst) (rX==rY); the dominant different-register case falls straight through to bl->insts[w++] and survives.

kit  (lvm _luaV_execute):              clang keeps the bytecode word live:
  str w10, [x29, #512]                   lsr  x8, x28, #7
  ldr w9,  [x29, #512]   ; w9 != w10      add  x8, x21, x8, lsl #4
  and w10, w9, #0xff                      ubfx w9, w28, #7, #8
  str w10, [x29, #512]                    ldr  x10, [x9]
  ldr w9,  [x29, #512]   ; again          (no stack round-trip at all)

Where / frequency. lvm: 1495 adjacent str;ldr same-slot different-reg (vs 79 same-reg already handled), 1962 within a 4-insn window; concentrated in luaV_execute. lz4: 191 intra-block store-then-adjacent-reload pairs (the two giant funcs). sqlite: ~8,500 store-then-reload-within-4. miniz: 1103 near same-slot store→reload. The single biggest cross-file contributor to the ldr/str excess (kit lvm ldr 4709 vs clang 731, str 3813 vs 214).

Impact. Each forwarded reload becomes a mov rY,rX, which the existing copy substitution then folds into rY's uses (often deleting the mov); when rX is dead and the slot has no other reader, the store is dead too (→ W8 stack-DSE + mir_dce). Conservatively 1400 insns in lvm alone (9% of the object), with real wins in lz4 (~380) / sqlite (intra-block subset) / miniz.

Host pass + sketch. pass_combine.c, opt_combine_compact_block. In the prev==IR_STORE && in==IR_LOAD && same_spill_slot_and_size branch, drop the same_reg_operand requirement: when the registers differ, rewrite the load in-place to an IR_COPY rY <- rX instead of keeping it as a memory load. The existing copy substitution / mir_dce retire the copy and (if rX dead + slot unread) the store. The store-DSE half is W8, already present.

Stays linear: single forward pass per block with the bounded last-store tracking the compact pass already does; no new analysis, no cross-block reasoning. Correctness boundary: only when no intervening clobber of rX, no aliasing memory write, and no redefinition of the slot between str and ldr — exactly the adjacency the compact pass already guarantees for the same-reg case.

Note vs O1.md: this is the natural extension of the W8 machinery, not a new pass. W8 today finds 0 sites because W2/DCE clear the store-store shape upstream; the store→load-forward-on-mismatch shape is a different and very live pattern that no landed item touches.

L2 — Fuse cmp; cset rD,cc; cbnz/cbz rDcmp; b.cc (boolean-into-branch) ★ broadest

The gap. For if (relational) goto L, kit materializes the condition into a GPR (cset rD,cc) and then re-tests it (cbnz/cbz rD), where clang branches directly off the flags. The original cmp's NZCV already encodes the branch; the cset is the sole user and dies at the branch.

kit  (yyjson _yyjson_arr_iter_init):   clang:
  cmp  w8, #0                            cmp  w8, #0
  cset w12, eq                           b.eq 0x604   (or cbz w8,0x604)
  cbnz w12, 0x604

Where / frequency — pervasive. yyjson 438, lvm 19 (→54 once L1 removes the intervening homing), lapi 27, lparser 5, lz4 10, sqlite (part of the cbnz +2,440 delta). clang emits ~0 of these. This is the most cross-file pattern in the catalog.

Impact. ~2 insns per site where a redundant cmp-against-0 also precedes the cset (yyjson's "double-cset", see L4), else 1 insn (the cset). yyjson 880 insns (2.1% of __TEXT); lapi ~27; broad small wins elsewhere.

Host pass + sketch. pass_combine.c (or pass_jump.c, which already owns IR_CMP_BRANCH/IR_CONDBR terminators). When a block terminator is IR_CONDBR whose condition register's most-recent same-block def is a single-use IR_CMP, fuse into IR_CMP_BRANCH carrying the cmp's CmpOp+operands (invert for the cbz/==0 case) and NOP the IR_CMP. This is the inverse of the fusion cg_ir_lower.c:941 already performs in the other direction; reuse the CombineCtx last_def map + the existing hard-live use counts.

Stays linear: same-block last-def lookup + single-use check, both already computed; no SSA.

L3 — Widen aggregate/memset zero-init (one strb per byte → wide stores) ★ cjson/miniz

The gap. aa_set_bytes (the AGG_SET / memset expander, aa64/native.c:2577) emits exactly one strb per byte in a flat 0..size loop, even for an aligned whole-struct/array zero. A 64-byte zero is 64 strb; clang does it in 3–4 (movi v0.16b,#0; stp q0,q0,...) or, scalarized, str xzr runs.

kit  (cjson _cJSON_PrintPreallocated):   clang:
  add  x8, x29, #16                        movi v0.16b, #0
  movz x9, 0x0                             stp  q0, q0, [sp, #32]
  strb w9, [x8]                            stp  q0, q0, [sp]
  strb w9, [x8, #1]                        ; 64 bytes in 3 insns
  ... (64 consecutive strb)

Where / frequency. cjson: 338 strb, a 64-long consecutive run confirmed (296 of 338 are zero-byte stores from this path; clang has 30 strb total). Hottest in _cJSON_PrintPreallocated/_PrintBuffered (64 each) and _print_number (26). miniz: large strb surplus from PNG/struct buffers.

Impact. Largest single win in cjson — ~250–300 insns / ~25% of cjson's 1236- insn gap. Even a scalar widening (str xzr for 8-aligned runs, str wzr/strh wzr/strb wzr tail) without NEON captures most of it.

Host pass + sketch. aa64/native.c aa_set_bytes: rewrite the per-byte loop to emit the widest aligned store covering the remaining run — stp q/str q if NEON is permitted, else str xzr, str wzr, strh wzr, strb wzr tail; or bl _memset above a size threshold. Pure per-call expansion, no analysis. The hardware zero register is already used for stored zeros (pass_native_emit.c).

Stays linear: it removes emitted instructions from a single expander; no new pass. (rv64/x64 set_bytes should get the same widening for parity, but aa64 is the measured win.)

L4 — Drop the redundant boolean re-normalize (cset; cmp rD,#0; cset) — yyjson

The gap. kit lowers (a==b) to cmp; cset rD,eq (a 0/1 bool), then a surrounding bool != 0 / if(bool) context lowers to a second cmp rD,#0; cset rD,ne that re-normalizes an already-0/1 value. The outer cmp+cset are a no-op.

kit  (yyjson _unsafe_yyjson_is_raw):   clang (at each inline site):
  cmp  w8, #1                            cmp  w8, #1
  cset w8, eq                            cset w0, eq
  cmp  w8, #0    ; redundant
  cset w8, ne    ; w8 == w8

Where / frequency. yyjson: 573 exact cset; cmp #0; cset triples (0 in clang); dense in the is_*/get_* predicate family. (lapi/sqlite have the related single-cset-of-a-bool but the triple is yyjson's signature.)

Impact. ~2 insns each → ~1100 insns / ~2.6% of yyjson __TEXT. Combines with L2: many of these feed a branch, so the L2 fusion subsumes the outer half.

Host pass + sketch. pass_combine.c same-block forward peephole: when an IR_CMP's source operand's most-recent same-block def is itself an IR_CMP (0/1 bool) and the comparison is against imm 0/1 with eq/ne, drop the outer IR_CMP and rewrite its uses to the inner result (inverting for the #0/ne case). Uses the existing last_def map + hard-live use counts.

Stays linear: single-block, single-use, checkable from existing state.

L5 — Single-use register copy not coalesced into its consumer

The gap. kit produces a value into one register then movs it into the register its sole consumer (a sxtw/store/call-arg/return) reads, instead of producing directly into the final register. The cross-block coalescer W3 cannot retire these because the destinations are multiply-defined physical pregs (W3's opt_copy_cleanup only fires when ndef[dst]==1); the per-block mir_combine substitution doesn't reach all the consumer paths.

kit  (lvm):                            kit  (lapi return):
  ldrb w13, [x8, #11]                    and w12, w12, #0x7
  mov  w12, w13   ; redundant            mov w0, w12   ; redundant
  sxtw x19, w12   ; sxtw x19,w13 ok      ret           ; and w0,w8,#0x7 ok

Where / frequency. Reg-to-reg mov wN,wM: lvm 330 vs clang 5; lapi 512 vs 194; lparser 948 vs 541; miniz 1018 of 3203 are mov-of-prev-insn-dest; yyjson 209 feed a uxtb + 59 are return copies (mov w0,wN before ret). The single largest mov contributor across the value-heavy files.

Impact. Several hundred insns across lapi+lparser+miniz+yyjson+lvm (conservative after excluding genuinely class-crossing or still-live moves).

Host pass + sketch. pass_combine.c post-RA peephole using the existing CombineCtx liveness (ctx_def_changed_since, count_uses_in_live_range): for mov rD,rS where rD has a single use in its live range before its next redef and rS is not redefined between the mov and that use, forward rS to the use and drop the mov. Extend the consumer set beyond what try_substitute/try_sink reach today: convert/extend, store-value, call-arg, and IR_RET value operands. The IR_RET→return-reg back-propagation mirrors the existing redundant-second-copy handling at pass_combine.c:~890.

Stays linear: the CombineCtx machinery already answers both guards; same-block.

L6 — Drop the redundant sxtb/sxtw after a same-width extending load

The gap. Two shapes. (a) yyjson loads a signed byte as ldrsb xD,[addr] (full 64-bit sign-extend) then emits sxtb wE,xD for a W-domain consumer — but xD's low 32 bits are already the sign-extended byte, so the sxtb is a no-op (and clang just does ldrsb wD). (b) lvm/sqlite sxtw of a value sourced from a zero-extending ldrb/ldrh: kit loads always zero-extend, so a 0..255 byte widens identically signed or unsigned → the sxtw is a same-width copy.

kit  (yyjson _yyjson_mut_ptr_getx):    clang:
  ldrsb x12, [x21]                       ldrsb w9, [x13]
  sxtb  w8, x12   ; x12<31:0> == byte    cmp   w9, #34
  cmp   w8, #47

Where / frequency. yyjson: 112 ldrsb x..; sxtb w.. + 74 ldrb; sxtb. lvm: the ldrb;mov;sxtw triple subset (~6 tight + more across the body). sqlite: part of the sxtw +2,582 (the ldrb/ldrh-rooted subset). This is the signed mirror of the already-landed ZEXT-of-load fold (OPT.md §3 / commit 8826982d).

Impact. yyjson ~186 insns; lvm ~30–80 from the byte-rooted cases; sqlite a slice of the sxtw delta. Medium confidence on the broad count, high on the exact-shape subset.

Host pass + sketch. pass_combine.c combine_exts (already folds ext-of-ext): a SXTB/SXTH/SXTW whose source's most-recent same-block def is a sign-extending load of equal-or-smaller width, or a zero-extending narrow load whose value can't have the sign bit set in the widened position, is redundant → drop it (rewrite uses to the load dst). Folding ldrb;sxtbldrsb needs a load-with-extend MemAccess rider (noted as structurally needed in prior O0 work); the pure sxtb-after-ldrsb/sxtw-after-ldrb drop needs no rider and is the easy win.

Stays linear: per-instruction, same-block last-def; no SSA.

L7 — Fold a single-use shift into the consuming ALU op (lsl;addadd ...,lsl #k)

The gap. kit folds shifts into memory operands (try_addr_synth handles ISHL into an indirect index scale) but not into general ALU consumers. So pointer scaling whose sum is stored/compared (not a load address) emits lsl xT,xS,#k; add xD,xB,xT where clang uses the one-instruction shifted-register form.

kit  (lapi _index2value):              clang:
  sxtw x12, w1                           sxtw x21, w1   ; once
  lsl  x12, x12, #4                      add  x8, x8, x21, lsl #4
  add  x8,  x13, x12

Where / frequency. lvm 14 lsl;add (+lsl;sub); miniz 105 lsl-feeds- add/orr/eor/sub (clang folds 74); lapi ~15–25; sqlite part of the lsl +1,335 delta. kit emits ~0 shifted-register ALU ops; clang uses them heavily. Strongest in miniz's LZ hash (eor ...,lsl #5) and byte-pack code.

Impact. miniz ~105 insns; lvm/lapi ~20–30 each; plus a freed scratch that relieves the spill pressure feeding L1.

Host pass + sketch. pass_combine.c recognition + aa64/native.c emission. Mark a single-use IR_BINOP SHL reg,imm (sh 1..4) feeding an IADD/ISUB/AND/ORR/ EOR and emit the fused shifted-register form. The emitter exists (aa_add_lsl, native.c:750; the ISA exposes AA64_FMT_LOG_SR/ADDSUB_SR) — it just isn't reachable for non-memory consumers. Needs a shift rider on the register operand (the current Operand only carries log2_scale inside the ind memory variant). x64 can use this only for IADD (LEA scale); rv64 has no shifted-add → skip there.

Stays linear: local single-use peephole, same live-range guards as the existing ISHL-into-EA path. Medium confidence (needs the operand-model shift-rider).

L8 — Fold a sxtw/uxtw index into the load/store addressing mode

The gap. For signed-int array indexing kit emits sxtw to widen the index, a separate add ...,lsl #scale to form the address, then a plain [reg] access — three instructions. aa64 has [Xbase, Wm, sxtw #scale] as a single addressing mode (aa_ldst_regoff, native.c:600); clang uses it everywhere, kit zero times.

kit  (miniz):                          clang:
  sxtw x14, w12                          ldr  w8, [x9, w8, sxtw #2]
  add  x9, x0, x14, lsl #2               strh w9, [x26, w13, sxtw #1]
  ldrh w20, [x9]

Where / frequency. miniz 15 sxtw;add...,lsl feeding a load/store (clang 98 extended-reg memory operands, kit 0). sqlite 546 sxtw immediately feeding a load/store offset. lapi/lparser index math. Big total across sqlite+miniz.

Impact. sqlite ~546 insns (the standalone sxtw folds into the access); miniz ~100–200 (removes sxtw + the address-forming add). LINEAR slice of the larger sxtw story (the cross-block redundant re-extend is NEEDS-SSA-O2, see §3).

Host pass + sketch. pass_addr_fold.c already builds OPK_INDIRECT with index + log2_scale but does not absorb a sxtw/uxtw of the index. Add an extend-into-index rule: fold a single-use sxtw/uxtw producer of an index operand into the indirect operand, recording the extend kind, and emit aa_ldst_regoff_v with the extend in aa64/native.c. The scaled-index infra + REGOFF encoding exist.

Stays linear: per-instruction forward fold, existing addr-fold machinery.

L9 — Constant-operand integer divide/multiply not folded

The gap. kit materializes two constants and issues a runtime udiv/sdiv/mul for fully compile-time-constant expressions (classically ArraySize = sizeof/elem, and the Lua MAX_SIZET/sizeof(T) >= LIMIT growvector guard). The guard's SIZE_MAX takes a 4-insn movz/movk chain into a register, then udiv + cmp + b.hi; clang decides the always-true compare and materializes only the LIMIT immediate.

kit  (sqlite _sqlite3_status64):       clang:
  movz x9, 0x50                          cmp w0, #0xa
  movz x10, 0x8
  udiv x8, x9, x10   ; = 10 at compile time
  cmp  w20, w8

Where / frequency. sqlite 108 div/mul sites with both operands freshly movz'd. lparser 22 udiv (12 udiv-by-1, 10 the SIZE_MAX guard); lapi 9 sdiv; tinyexpr 5. The SIZE_MAX guard is the dominant reason lparser is larger than clang.

Impact. sqlite ~300–400 insns (each site collapses movz+movz+udiv+mov). lparser ~80–90 (the guard is ~7–8 insns → 1 movz at ~10 sites + the udiv-by-1). Each udiv is also the slowest integer op, so a latency win too.

Host pass + sketch. Two pieces. (a) pass_simplify.c: add a same-block forward LOAD_IMM→known-value tracker (per-block reg→value map, invalidated on redef/block boundary — no SSA, consecutive within-block) and feed it into operand_const so the existing BO_UDIV/BO_SDIV folds and a new const-op-const fold fire when the constant lives in a register rather than an inline OPK_IMM. The resulting LOAD_IMM then lets simplify_cmp decide the always-true guard. (b) The divide-by-1 → copy/sub falls out of (a).

Stays linear: a bounded per-block reg map + the existing folds. Strength-reduction of non-constant divide-by-constant (magic multiply, miniz adler32) is a separate, also-linear pass_lower.c item but lower priority (~25 sites, medium confidence).

L10 — Frame elision on no-spill leaf functions

The gap. kit emits a full stp x29,x30,[sp,#-16]!; add x29,sp,#0 ... ldp frame in functions that are leaves (no call), spill nothing, and never reference [x29] — i.e. need no frame. clang omits it entirely; for a one-op accessor the frame is the majority of the function.

kit  (tinyexpr _add):                  clang:
  stp x29, x30, [sp, #-16]!              fadd d0, d0, d1
  add x29, sp, #0                        ret
  fadd d0, d0, d1
  ldp x29, x30, [sp], #16
  ret

Where / frequency. yyjson 90 frameless-able leaves; lapi ~21; lparser ~10; tinyexpr 8. The is_*/get_*/cast accessor family. (Caveat: many of these are exactly the predicates clang inlines away, so the realizable win depends on whether kit also inlines them — the frame-elision is independently correct for the leaves that remain.)

Impact. ~3 insns/function (stp+add+ldp). yyjson ~360, lapi ~63, lparser ~30, tinyexpr ~24. Medium confidence on realizable total (the inlining caveat).

Host pass + sketch. aa64/native.c prologue/epilogue (NativeFrame): a per-function needs_frame flag = false when no IR_CALL, no spill slots, no escaping IR_ADDR_OF(local), no varargs. All known at frame-finalize time in one pass; emit the stp/add/ldp only when set. x29 already sits at frame bottom (W1.1), so omission is straightforward.

Stays linear: single per-function check, no analysis.


3. Needs SSA / the O2 mid-end

Real gaps, but none is a linear no-SSA peephole — each maps to a parked O2 item (OPT.md §3 schedule, pass_o2.c/pass_ssa.c; O1.md §4 out-of-scope list).


4. Not a deficiency

Where clang is bigger via inlining/unrolling, or kit is already smaller — so future readers don't chase these.

Downgraded on spot-check: the lz4/miniz "address bases spilled and reloaded" and "large struct-field address rebuilt per use" items the per-file agents rated high were largely the cross-block residency problem (NEEDS-SSA-O2, §3), not a clean linear peephole — only their strictly-intra-block, same-base-unchanged subset is linear, and that subset is already covered by L1 (store→load forwarding) and the landed W1a (frame-address sub/add-CSE) + W5 (local CSE). They are not given separate §2 entries to avoid double-counting.


5. Suggested next O1 work

In the style of O1.md's worklist — ranked by impact × confidence × breadth, each a linear no-SSA change with a clear host pass and a test/opt/ structural guard.

  1. P1 — store→load forwarding on register mismatch (pass_combine.c, opt_combine_compact_block). Highest single lever (lvm ~1400 insns, plus lz4/ sqlite/miniz intra-block). Drop the same_reg_operand requirement in the store;load branch; emit a copy on mismatch, let substitution + W8 + mir_dce clean up. Guard: assert the str;ldr-different-reg pattern is gone on an lvm fixture.
  2. P2 — cset;cbnz/cbzb.cc fusion (pass_combine.c/pass_jump.c). Broadest cross-file win (yyjson 438, lapi 27, lvm/lz4/sqlite). Fuse IR_CONDBR of a single-use IR_CMP into IR_CMP_BRANCH; inverse of the existing cg_ir_lower fusion.
  3. P3 — widen aa_set_bytes zero-init (aa64/native.c). ~25% of cjson's gap; helps miniz. Emit str xzr/stp q0 aligned runs (or bl _memset) instead of per-byte strb. Self-contained expander change.
  4. P4 — drop yyjson double-cset + redundant sxtb-after-ldrsb (pass_combine.c / combine_exts). ~1100 + ~186 insns on yyjson. Same-block last-def peepholes; the sxtb-drop is the signed mirror of the landed ZEXT-of-load fold.
  5. P5 — constant-operand div/mul fold + same-block LOAD_IMM const tracker (pass_simplify.c). Fixes lparser being larger than clang (the SIZE_MAX guard) + sqlite's 108 const-divide sites. A bounded per-block reg→value map feeding the existing BO_UDIV/SDIV folds.
  6. P6 — single-use copy coalescing into convert/store/call-arg/return consumers (pass_combine.c) and sxtw-index-into-addressing-mode (pass_addr_fold.c). The mov and standalone-sxtw surplus across the value-heavy files; both reuse existing CombineCtx/addr-fold machinery.

Definition of done per item: measurable __TEXT/instruction reduction on the affected corpus files (via scripts/o1_quality.sh), sqlite -O1 compile time unchanged (linearity held — the §8 synthetic sweep), all correctness gates green (make test-opt test-toy, ecosystem -O0/-O1 vs clang, smoke-x64/rv64), and a test/opt/ structural disasm guard added.

Sequencing note: P1 + P3 are the two biggest size levers and touch disjoint files (pass_combine.c vs aa64/native.c) → parallelizable. P2/P4/P5/P6 share pass_combine.c/pass_simplify.c → one owner, land + re-measure one at a time (gate = correctness, not byte-identity). The true ceiling on lvm/sqlite/miniz/lz4 remains the SSA register allocator (§3) — these linear items close the local waste, not the over-spilling.