Skip to content

docs(vcr-ra): resolve #470 — optimized-path ABI model is non-AAPCS by design#473

Merged
avrabe merged 1 commit into
mainfrom
vcr-ra/470-optimized-abi-model
Jun 24, 2026
Merged

docs(vcr-ra): resolve #470 — optimized-path ABI model is non-AAPCS by design#473
avrabe merged 1 commit into
mainfrom
vcr-ra/470-optimized-abi-model

Conversation

@avrabe

@avrabe avrabe commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Resolves #470 (analysis-only, frozen-safe — no codegen change; frozen gate green).

Determination: by-design, not a bug

synth has two ABI models selected by --relocatable:

optimized (default) --relocatable
codegen ir_to_arm select_with_stack
AAPCS no — by design yes
use self-contained image (synth controls all callers) host-link / external AAPCS callers

Documented in arm_backend.rs: the optimized path "does not preserve caller-saved registers across calls." The callee-saved clobber #470 spotted is the same fact deeper: ir_to_arm emits no callee-saved push and its temp pool prefers r4-r8.

Self-consistency verified (intra_module_callee_saved.wat)

A call-containing function is declined to the direct selector, which holds across-call values on the frame (caller a: str [sp] before bl, ldr [sp] after — never relies on the callee preserving r4-r8) and pushes/pops {r4-r8,lr} for its caller. So an optimized leaf's clobber corrupts nothing intra-module. The only exposure is an external AAPCS caller — for which --relocatable is the required, documented path. No fix warranted.

Bonus: clears the VCR-RA-002 baseline worry (#471)

The measured push {r4-r8,lr} is on the call-containing/relocatable path, not optimized leaves — so #470 does not reset VCR-RA-002's baseline.

Adds the generic evidence fixture + an ABI-model note.

Refs #470, #428, #242

🤖 Generated with Claude Code

… design (analysis)

#470 asked whether the optimized (non-relocatable) path emitting an exported leaf
that clobbers callee-saved r4-r8 with `bx lr` and no push is an AAPCS violation.

Determination: by-design, not a bug. synth has two ABI models selected by
--relocatable: the optimized path is the self-contained bare-metal model (non-AAPCS
by design — documented in arm_backend.rs: "does not preserve caller-saved registers
across calls"; ir_to_arm also emits no callee-saved push and its temp pool prefers
r4-r8), and --relocatable is the AAPCS/host-link path (select_with_stack, fp-relative,
proper preservation).

The self-contained model is self-consistent (verified — intra_module_callee_saved.wat):
a call-containing function is declined by the optimizer to the direct selector, which
holds across-call values on the FRAME (caller `a`: str [sp] before `bl`, ldr [sp]
after — never relies on the callee preserving r4-r8) and pushes/pops {r4-r8,lr} for
ITS caller. So an optimized leaf's callee-saved clobber corrupts nothing intra-module;
the only exposure is an external AAPCS caller, for which --relocatable is the required
documented path. No fix warranted.

Also resolves the VCR-RA-002 (#471) baseline worry: the measured `push {r4-r8,lr}` is
on the call-containing/relocatable path, NOT optimized leaves — so #470 does not reset
VCR-RA-002's baseline.

Adds the generic evidence fixture + the ABI-model note.

Refs #470, #428, #242

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@avrabe avrabe merged commit b3313d1 into main Jun 24, 2026
10 checks passed
@avrabe avrabe deleted the vcr-ra/470-optimized-abi-model branch June 24, 2026 20:21
@codecov

codecov Bot commented Jun 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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.

Optimized (non-relocatable) path: exported leaf clobbers callee-saved r4-r8 without save/restore (potential AAPCS violation)

1 participant