Skip to content

Stop counting non-returning trap clobbers against live ranges - #2107

Merged
steveklabnik merged 1 commit into
trunkfrom
claude/incremental-recompile-4w4oah
Aug 5, 2026
Merged

Stop counting non-returning trap clobbers against live ranges#2107
steveklabnik merged 1 commit into
trunkfrom
claude/incremental-recompile-4w4oah

Conversation

@steveklabnik

Copy link
Copy Markdown
Collaborator

Rue lowers each checked +/* as jno .L; call __rue_overflow; .L:, and that trap call sat inside almost every arithmetic value's live range — disqualifying it from #2101's caller-saved allocation. Checked-arithmetic-heavy code kept spilling for a call that, if it executes, never comes back.

The non-returning fact comes from the ABI manifest, not inference. rue-runtime-abi already declares ReturnBehavior::Never per helper (all nine verified to end in platform::exit); MIR lowering dropped it. Call instructions now carry it: a never-returning call has no successors (empty live-out), and ClobberIndex skips its clobber events — the clobber is real but unreachable by any later use, since control continues only on the no-trap path. Trap-argument uses stay ordinary uses at the call index, so the trap ABI's own live-in needs are untouched.

Both pieces are necessary, verified empirically: live ranges are textual [first, last] intervals, so with only the successors change applied the demo assembly was byte-identical to baseline — the index change is what unlocks allocation, the successors change is the honest model behind it. The demo function now holds a value in r11 across call __rue_overflow and drops a callee-saved push from the prologue (AArch64 mirrors with x13/x14 across bl).

Also lands the RUE-1146 follow-up guard: an always-on pre-allocation assertion (codegen has no debug-assert allowance per docs/process/ci.md) that lowering never names an allocatable register as a physical operand, reusing both schedulers' exhaustive operand enumerations rather than adding a third.

Fixes RUE-1224.

Two observations being filed as follow-up: preferring REX-prefixed R11 over Rbx costs +0.05% code size on arithmetic-heavy x86-64 (a size-aware tiebreak when Rbx is already saved would recover it), and the textual-interval range builder means future liveness refinements will always need this two-part treatment.

Validation

Premerge (78/78), codegen units 657 (+9 new incl. per-backend #[should_panic] guard tests), cfg 239, quick (re-run green; one transient rue-test build-race in the first run passed 213/213 in isolation), trap/overflow CLI suites (mul_overflow/intcast/panic_assert/subword/division/divergence), abi/borrow/multi, differential-oracle targets, 600-seed oracle fuzz (600/600 agree), 300 generated programs × -O0/-O1/-O2/-O3 self-consistency sweep (0 divergences), reproducible-programs, clippy, fmt. Trap behavior unchanged (same message, same exit code).


Generated by Claude Code

The runtime ABI manifest already declared which helpers never return;
MIR lowering dropped that on the floor, so every checked add or mul's
trap call sat inside the value's live range and disqualified it from
caller-saved allocation. Call instructions now carry the helper's
return behavior: a never-returning call has no successors (empty
live-out), and ClobberIndex skips its clobber events -- the clobber is
real but unreachable by any later use, since control only continues on
the no-trap path. Live ranges are textual intervals, so the successors
change alone is not sufficient; both pieces verified byte-level. Trap
argument uses stay ordinary uses at the call index. Also adds the
always-on pre-allocation guard that lowering never names an allocatable
register as a physical operand, reusing the schedulers' exhaustive
operand enumerations.
@steveklabnik
steveklabnik marked this pull request as ready for review August 5, 2026 06:18
@steveklabnik
steveklabnik enabled auto-merge August 5, 2026 06:19
@steveklabnik
steveklabnik added this pull request to the merge queue Aug 5, 2026
Merged via the queue into trunk with commit ecb2340 Aug 5, 2026
22 checks passed
@steveklabnik
steveklabnik deleted the claude/incremental-recompile-4w4oah branch August 5, 2026 06:33
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.

2 participants