agourakis82 opened PR #14373 from agourakis82:users/agourakis/cranelift-regionless-load-alias-fence to bytecodealliance:main:
Summary
Alias analysis keyed regionless loads only on
last_fence. A later named-region store therefore did not invalidate the regionless load's memory version, so store-to-load / load-to-load forwarding and DSE could drop an intervening region store that the regionless load still observes (#14323).Fix
- When computing the last-store version for a regionless access, meet every named-region slot with
last_fence(collapses toUnknownif any named store happened since the fence).- When a regionless load observes memory, observe all region stores as well as the last fence (same shape as an all-region observer).
- Update
alias/no-region.clifso its first case matches the corrected invariant: a regionless load keeps a preceding named-region store observable.Test plan
- New:
cranelift/filetests/filetests/runtests/issue-14323-regionless-load.clif(both issue repros)- Updated:
cranelift/filetests/filetests/alias/no-region.clif- Local:
clif-util teston the issue repros,alias/,runtests/alias.clif,egraph/alias_analysis.clifFixes #14323
AI assistance
Developed with AI tool assistance (Claude Code) under human direction and review. I am the author of record, reviewed the generated diffs before opening the PR, and can answer questions about the change during review.
agourakis82 requested wasmtime-compiler-reviewers for a review on PR #14373.
agourakis82 requested fitzgen for a review on PR #14373.
github-actions[bot] added the label cranelift on PR #14373.
agourakis82 commented on PR #14373:
Thanks @cfallin — this is the key design question.
I read the issue as Alex framed it (regionless load may still observe a named-region store to the same address), and the PR follows that reading. Your preferred model — “no region” as its own disjoint bucket, with no globally-aliasing ops — matches the existing module docs /
no-region.clifcomment much more closely, and would make the original#14323tests frontend-invariant violations rather than mid-end bugs.I’m happy to treat this PR as provisional pending the Cranelift meeting pin-down:
- if the meeting keeps “no region == disjoint other”, I can close/revert this and we can close
#14323as invalid IR;- if the meeting decides regionless may alias named regions, this patch (or a tightened variant) stays useful.
Either outcome is fine with me; I just want the invariant written down one way so alias analysis and frontends don’t diverge.
agourakis82 commented on PR #14373:
Follow-up design writeup on the issue, focused on the existing store/load asymmetry:
https://github.com/bytecodealliance/wasmtime/issues/14323#issuecomment-5778631844
(see the newer comment just posted with the G vs D table)
@fitzgen you already own most of this file — a one-line call on G vs D unblocks either keeping this PR or replacing it with the disjoint-other store demotion.
agourakis82 commented on PR #14373:
Correction — full G vs D writeup with the store/load asymmetry table is here:
https://github.com/bytecodealliance/wasmtime/issues/14323#issuecomment-5778672877
@fitzgen a one-line call on G (regionless = may-alias-all; keep this PR) vs D (regionless = disjoint other; demote regionless stores from fence and close this PR) unblocks the resolution either way.
agourakis82 updated PR #14373.
agourakis82 commented on PR #14373:
Rebased on latest
main.Also: I prototyped Model D locally; it breaks
alias/issue-13508.clif, whose runtest requires a regionless store to clobber a later named-region load ([-1,-1,42]). Writeup on the issue:https://github.com/bytecodealliance/wasmtime/issues/14323#issuecomment-new
(see latest comment titled “Model D is falsified by an in-tree runtest”)
So this PR remains the load-side consistency fix for the store semantics already in tree.
agourakis82 commented on PR #14373:
Correction — falsification writeup URL:
https://github.com/bytecodealliance/wasmtime/issues/14323#issuecomment-5779157701
issue-13508’s run expectation ([-1, -1, 42]) requires regionless stores to be visible to named-region loads. Model D cannot satisfy that without declaring the test invalid. This PR keeps Model G and only fixes the load side.
agourakis82 commented on PR #14373:
Parking this on the meeting outcome for “explicit no-region” vs “no-region as fence”.
I’m fine either rewriting this PR toward the January explicit-no-region store behavior, or keeping the load-side fence consistency — whichever gets pinned down.
agourakis82 edited a comment on PR #14373:
Thanks. Parking this on the meeting.
#14373 follows the issue report’s reading (no-region load can see a named-region store). If the call is explicit no-region, I’ll rework/close it.
agourakis82 edited a comment on PR #14373:
Wrote up the store/load asymmetry on the issue.
agourakis82 edited a comment on PR #14373:
Better summary of the two options is here: https://github.com/bytecodealliance/wasmtime/issues/14323#issuecomment-5778672877
agourakis82 edited a comment on PR #14373:
Rebased on main.
Tried the explicit-no-region store change locally; notes on the issue.
agourakis82 edited a comment on PR #14373:
https://github.com/bytecodealliance/wasmtime/issues/14323#issuecomment-5779157701
agourakis82 edited a comment on PR #14373:
Parking on the meeting: explicit no-region vs no-region as fence. Fine either way.
agourakis82 edited PR #14373:
Regionless loads were only keyed/observed via
last_fence, while named-region stores updateregions[r]. That lets forwarding/DSE miss an intervening named store that a later regionless load can still see (#14323).This patch makes regionless loads meet/observe the named-region slots as well (matching how regionless stores are already treated as fences).
Also updates
alias/no-region.clifand addsruntests/issue-14323-regionless-load.clif.Parking on the meeting for “explicit no-region” vs “no-region as fence”; happy to rework if the call goes the other way.
Fixes #14323
Assisted-by: Claude
agourakis82 updated PR #14373.
Last updated: Oct 11 2026 at 04:10 UTC