You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Whilst trying to improve #7682, I came across the following bug:
SROA was generating invalid IR when an aggregated had loads across multiple blocks. When generating the scalar accesses, the older algorithm was gathering only the "last" block that had access, and incorrectly generating loads pointing to this last block, even when the load was from a previous block. A "use-before-def" problem. (see sway-ir/tests/sroa/cross_block_gep_reuse.ir).
To verify this issue this PR also creates an "SSA dominance check". We check if all "uses" are dominated by all its "defs". But this check is expensive, so, for the moment, this check is opt-in. Below we have some timings to justify that:
dominance check off:
> hyperfine "cargo r -p forc -r -- build --path fuel-o2-exports/contracts/order-book --release"
Benchmark 1: cargo r -p forc -r -- build --path fuel-o2-exports/contracts/order-book --release
Time (mean ± σ): 11.213 s ± 0.100 s [User: 8.347 s, System: 1.095 s]
Range (min … max): 11.105 s … 11.383 s 10 runs
dominance check on:
> SWAY_FORCE_VERIFY_IR=true hyperfine "cargo r -p forc -r -- build --path fuel-o2-exports/contracts/order-book --release"
Benchmark 1: cargo r -p forc -r -- build --path fuel-o2-exports/contracts/order-book --release
Time (mean ± σ): 16.663 s ± 0.577 s [User: 13.563 s, System: 1.121 s]
Range (min … max): 16.358 s … 18.271 s 10 runs
This PR also removes DCE and MEM2REG passes. from the SROA test. They were there to facilitate filecheck directives. As we do not use them anymore, seeing the diff as it is, is actually better.
Checklist
I have linked to any relevant issues.
I have commented my code, particularly in hard-to-understand areas.
I have updated the documentation where relevant (API docs, the reference, and the Sway book).
CI shows 36/42 checks successful, 1 pending (policy-bot), 5 skipped (expected for non-release)
SROA Fix (correct)
The root cause was that SROA used a single global FxHashMap<Value, Value> for replacements, then called function.replace_values() at the end. When the same GEP pointer was used across multiple blocks, later blocks overwrote earlier mappings, causing all uses to point to a get_local defined only in the last block (use-before-def). The fix correctly scopes replacements per-block via replacements_per_block and calls block.replace_values() per block. The cross_block_gep_reuse.ir test directly targets this bug.
SSA Dominance Verifier (correct)
The new SSADominanceScopeChecker properly checks that every operand is dominated by its definition, using the existing dominator infrastructure. It's gated behind context.verify_ssa_dominance and enabled in tests via run_passes_with_verify. The compute_dom_tree_from_po extraction is a clean refactor.
Minor note: When running with SWAY_FORCE_VERIFY_IR=true, the cse test fails due to a pre-existing bug where CSE incorrectly reports modified: true on idempotent runs. This is not caused by this PR — it's a latent CSE issue now exposed by routing tests through run_with_print_verify. Normal CI does not set this env var, so it doesn't affect CI.
xunilrj
changed the title
Fix sroa load multi blocks
Fix SROA when loading in multiple blocks
Jul 22, 2026
ironcev
added
compiler
General compiler. Should eventually become more specific as the issue is triaged
compiler: ir
IRgen and sway-ir including optimization passes
labels
Jul 23, 2026
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
compiler: irIRgen and sway-ir including optimization passescompilerGeneral compiler. Should eventually become more specific as the issue is triaged
2 participants
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.
Description
Whilst trying to improve #7682, I came across the following bug:
SROA was generating invalid IR when an aggregated had
loads across multiple blocks. When generating the scalar accesses, the older algorithm was gathering only the "last" block that had access, and incorrectly generatingloads pointing to this last block, even when theloadwas from a previous block. A "use-before-def" problem. (see sway-ir/tests/sroa/cross_block_gep_reuse.ir).To verify this issue this PR also creates an "SSA dominance check". We check if all "uses" are dominated by all its "defs". But this check is expensive, so, for the moment, this check is opt-in. Below we have some timings to justify that:
This PR also removes
DCEandMEM2REGpasses. from the SROA test. They were there to facilitatefilecheckdirectives. As we do not use them anymore, seeing the diff as it is, is actually better.Checklist
Breaking*orNew Featurelabels where relevant.