test(gc): scope the #7114 IR assertions to the function under test - #7120
Merged
Conversation
added 2 commits
July 31, 2026 07:32
…7116 review) ir_for returns the WHOLE module, so a bare .find() over it answers with whichever function comes first in the file. Every ordering assertion in the #7114 section is now sliced to @main via function_ir/init_ir and paired with an exact count of the operand-specific opcode inside that slice, so 'this is the operand I meant' is a property of the test rather than of module layout. Claude-Session: https://claude.ai/code/session_018ZFER8EEg8K7ez2n6oDrT9
📝 WalkthroughWalkthroughThe tests now extract LLVM IR for ChangesLLVM IR regression tests
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #7116 (merged as
57f9dc31b). Addresses the CodeRabbit finding thatwas submitted at 05:03:58 — one minute after the last commit — and so was never
looked at before the merge.
Test-only. No codegen change:
git diff 57f9dc31b HEAD -- 'crates/*/src'isempty.
The finding, and why it is not trivial
CodeRabbit labelled it Trivial. For a test whose entire job is proving that a
value is re-derived below a collection point, an assertion satisfiable by
some other function's IR is precisely the wrong test. It applied to more than
the WTF-8 case: every ordering assertion added in #7114 searched whole-module IR.
What changed
function_ir/init_irslice onedefineout of the module. Module-levelinitstatements lower into the entry module's@main, so that is the slice.count of the operand-specific opcode inside it — order plus count makes
"this is the operand I meant" a property of the test rather than of module
layout. The concat and array tests now assert exactly two loads of that
literal's own handle global: one where the operand is lowered, one re-derived
below the collection point. One load is the String literal operand is not GC-rooted across an allocating call in the same expression (stale handle after evacuation) #7114 bug; three would mean
something else is re-lowering it.
init_ir_slices_only_the_function_under_testasserts the slice is one function, strictly smaller than the module, and does
not reach
__perry_init_strings_*— the other function in these modules thattouches the same handle globals.
Sabotage, four directions
Host:
perry@perry-macos.local(Apple M1, 8 cores),--release. Every arm belowwas run against the scoped assertions, so this is evidence that scoping did
not weaken them.
temp_root.rs+new.rstoff85fd483)concatandarray_elementFAIL; other 10 passcollectswindow)..._not_re_derived_when_nothing_collectsFAILS; other 11 passWtfStringsuppressed inoperand_needs_rootonly)wtf8_..._rooted_not_merely_reusedFAILS; other 11 passinit_ir(return the whole module)init_ir_slices_only_the_function_under_testFAILS; other 11 passClean run: 12/12 pass.
The fourth row is worth reading honestly: with
init_irun-scoped, the othereleven tests still passed. In these single-statement modules the unscoped
.find()happened to land on the right function, so the flaw was latentfragility rather than a live false pass — which is exactly why it needed a gate
rather than an argument. It has one now.
Gates
Because
crates/*/srcis byte-identical to mergedmain, the #7116 matrix andgc-ratchetresults carry unchanged; both are restated here with the identityproof, plus a fresh single-arm ratchet on merged
main.--arms all --pressure 8(on57f9dc31b's compiler):PASS=379 UNVER=100 XFAIL=1 FAIL=0over 480 cells, byte-exact vsnode v26.5.1on 479/480. The#7114corpus row is PASS on all 20 arms andlive on the moving ones (
evac_minor: 66 cycles / 1 506 487 scavenged;default: 50 cycles / 1 121 856 scavenged).gc-ratchet — run locally, pinned-host profile
CI is not the gate (runner pool hours deep;
GC Ratchethas been cancelled onconsecutive
maincommits without reaching a runner), so this was run on themachine the baseline is pinned to —
perry-macos.fritz.box, Apple M1, 8 cores,which is the exact host recorded in
benchmarks/gc_ratchet/baseline/gc-ratchet-v1.json.1. Current gate, on merged
main's compiler (run_gc_ratchet_baseline.sh --check,pinned_hostprofile, quiet host confirmed atcpu_active=5.4%):96 gated rows
ok/improvement, 0 regressions;correctness=passagainstnode v26.5.1on all 8 probes;heap_used_bytesandheap_total_bytes0.00%drift on every probe. The one non-zero semantic drift against the pinned
baseline is
07_array_grow_evacuate.copied_objects18 294 → 18 290 (−0.02%,band 5%), which is the documented sub-0.1% host-dependent component of the
evacuation counters — and it is not from #7114, because the base-vs-fix A/B
below has that counter bit-identical.
2. Base-vs-fix A/B isolating #7114 (
ff85fd483vsff85fd483+#7114, botharms
--check, exit 0 for both):wall_msrss_bytesnode v26.5.1The ungated spread is the load-bearing half. Bit-identical gated counters are
also exactly what a vacuous A/B looks like when a stale
.amakes both armsthe same binary, so a nonzero ungated spread on every row is the evidence that
the two binaries genuinely differed. Independently confirmed by fingerprint:
perrysha2562df0831b…(base) vs86d9575a…(fix), withlibperry_runtime.abyte-identical at143b184c…— correct, since #7114 is acodegen-only change, so the archive should be identical and the differing
artifact should be
perryitself.Why the A/B was not re-run for this PR: it would be vacuous by construction.
This PR changes only a test file, so both arms would be the same compiler. The
A/B above is the correct isolation of the #7114 change, and
git diff 57f9dc31b HEAD -- 'crates/*/src'being empty is what licensescarrying it forward.
Gap parity suite (partial, informational)
./run_parity_tests.sh --filter test_gap_on mergedmain's compiler, stoppedat 166/438 to free the host for the ratchet (the ratchet needs a quiet host
and the suite was pacing at ~4 hours). Three failures, none attributable to
#7114:
test_gap_2159_defineproperty_class_prototypetest-parity/known_failures.jsontest_gap_2514_settracesiginttest-parity/known_failures.jsontest_gap_6301_event_target_subclassff85fd483, so pre-existing. It is the native-base-subclassing weak area; aknown_failures.jsonprovenance gap (#797).