Skip to content

feat(vcr-ra): i64 pair-spill via param frame-backing — VCR-RA-001 acceptance closes (v0.11.40)#325

Merged
avrabe merged 1 commit into
mainfrom
feat/vcr-ra-pair-spill
Jun 11, 2026
Merged

feat(vcr-ra): i64 pair-spill via param frame-backing — VCR-RA-001 acceptance closes (v0.11.40)#325
avrabe merged 1 commit into
mainfrom
feat/vcr-ra-pair-spill

Conversation

@avrabe

@avrabe avrabe commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

The last criterion

The #242 acceptance review left one gap: "a high-pressure i64 module compiles with no hard-fail." Investigation revised the diagnosis: the pair-spill loop already existed (#171) — the true blocker was pinned param home registers (#193's reserved, up to R0–R3) which no stack spill can free. The fix is a third retry mode that forces the proven #204 param frame-backing onto call-free functions, emptying the reserve; pigeonhole over the freed pool then guarantees a consecutive pair.

Backend retry ladder (each pass only on its predecessor's exact Err, so bit-identity stays structural): default → spill-only (#320) → spill+param-backing (this PR).

Evidence

VCR-RA-001 status after this merges: all five criteria met

compile-no-hard-fail ✅ (both pressure classes) · fixtures bit-identical ✅ · cycles equal-or-better ✅ (gale silicon) · cost-gate revert ✅ (executed, #322) · validator guarding ✅ (#323). Honest bounds named: the 8-slot spill pool, the distinct R8-pair/i64-param-convention class (epic-tracked), stack-passed params.

Release: v0.11.40 — the allocator's acceptance release.

🤖 Generated with Claude Code

…iterion closes (#242)

The last hard-fail named by the v0.11.40 acceptance review: a high-pressure
i64 module now compiles with no hard-fail.

ROOT CAUSE (differs from the review's reading): the pair allocator
(alloc_consecutive_pair) has ALWAYS spilled register-resident stack values —
pair-aware, both halves into one 8-byte slot (#171). The remaining
"no consecutive pair of free registers for i64" Err fires only when the
operand stack holds nothing register-resident and the blockers are the
PINNED PARAM HOME REGISTERS (#193 `reserved`, up to r0-r3) plus the popped
operand pairs (`extra_avoid`, up to 4 regs) — 8 of the 9-register pool, no
pair left, and no amount of stack spilling can free a param home register.

FIX (same structural-bit-identity pattern as #320): a third retry mode,
`set_param_backing_on_exhaustion`, forces the proven #204 `param_slots`
frame-backing for call-free functions — params spill to frame slots at entry
and reload on read, so `reserved` empties and a free consecutive pair always
exists after stack spilling (extra_avoid is at most two adjacent pairs among
nine registers; pigeonhole over the free segments). The backend's
select_direct ladder: pass 1 default → pass 2 spill-only (#320, on the
single-reg Err) → pass 3 spill+param-backing (on the pair Err). Functions
that compile on an earlier pass are selected by exactly yesterday's code.
Loop bound unchanged: each spill_deepest_reg iteration converts one
StackVal::Reg to Spilled. Honest remaining bound: the i64 spill-slot pool
("spill-slot pool exhausted"), deliberately NOT retried.

EVIDENCE
- scripts/repro/high_pressure_i64.wat: 4 simultaneously-live i64 consts +
  4 pinned i32 params. On main: skipped with the exact pair Err. On this
  branch: compiles; high_pressure_i64_differential.py (unicorn vs wasmtime,
  i64 result in r0:r1, large/negative vectors) 6/6 ORACLE PASS.
- Bit-identity vs origin/main (cortex-m4, per differential headers):
  control_step 8248…32f6, div_const cada…45ede, flight_seam_flat 03ce…8579,
  high_pressure_i32 355c…e6c2 — all pairwise sha256-identical; all three
  frozen differentials ORACLE PASS on the branch.
- Tests: 5 new (pair victim spill, single victims, pinned-blockers Err
  preserved verbatim, spilled-pair reload on pop, end-to-end 3-pass ladder);
  synth-synthesis 382 lib tests green; workspace 1468 passed / 0 failed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@codecov

codecov Bot commented Jun 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.79167% with 10 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/synth-backend/src/arm_backend.rs 80.00% 7 Missing ⚠️
crates/synth-synthesis/src/instruction_selector.rs 98.08% 3 Missing ⚠️

📢 Thoughts on this report? Let us know!

@avrabe avrabe merged commit 84e7aaf into main Jun 11, 2026
14 checks passed
@avrabe avrabe deleted the feat/vcr-ra-pair-spill branch June 11, 2026 13:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant