fix(vpto): hoist loop-invariant guarded address chains out of scf.if - #1347
Merged
Merged
Conversation
jimmychou0
force-pushed
the
zjm/issue-fix-1328
branch
3 times, most recently
from
August 25, 2026 12:26
4c2cc10 to
32a2e3b
Compare
jimmychou0
marked this pull request as ready for review
August 26, 2026 00:39
Generic MLIR LICM only inspects the top-level operations of an scf.for body, so a loop-invariant base-address chain computed inside an scf.if guard whose condition depends on the induction variable is never hoisted, and the whole guard cannot be hoisted either (IV-dependent condition plus side-effecting memory ops). Add the vpto-guarded-licm pass (A5 VPTO only) which extracts pure, speculatable scalar/address subexpressions of guarded regions and moves them in dependency (topological) order in front of the enclosing scf.for, leaving IV-dependent arithmetic, side-effecting operations, div/rem and vector/tile computations in place. Loops are processed innermost-first so invariant chains climb out through nested guards and nested loops. The pass is wired between vpto-soft-postupdate and the generic LICM. Tests: focused vpto-guarded-licm cases (basic, nested if, nested loops, IV-dependent and non-speculatable negatives) plus an end-to-end pto.section.simt -> outlined helper -> VPTO pipeline regression.
jimmychou0
force-pushed
the
zjm/issue-fix-1328
branch
from
August 26, 2026 01:19
32a2e3b to
adab685
Compare
A3 板测完成(有跳过)
|
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.
Closes #1328
Root cause
The VPTO emission pipeline already runs the generic MLIR
LoopInvariantCodeMotionpass, but MLIR LICM only enqueues the top-level operations of thescf.forbody. For the guarded access pattern in the issue:the invariant base-address chain inside the guard is never exposed to LICM, and the surrounding
scf.ifcannot be hoisted either (IV-dependent condition plus side-effecting memory ops). This is an optimization gap of the generic LICM across guarded regions — not a missing pass or a missingPureattribute.Change
Add a narrow
vpto-guarded-licmpass (func::FuncOpscope, A5 VPTO only), wired betweenvpto-soft-postupdateand the generic LICM:scf.forloops innermost-first so invariants can climb out through nested guards and nested loops.integer,index,pto.ptrresults) insidescf.ifregions and builds their dependency closure; only ops whose operands are defined outside the loop or by already-hoisted ops are moved.iter_args-dependent expressions, side-effecting ops (load/store/call),div/remwith unknown divisors, vector/mask/tile computations, and ops inside nestedscf.forregions.For the issue's repro, the
w64/slot/range_base-style base chain moves in front of the loop while the IV-dependent dynamic offset stays inside the guard.Tests
test/lit/vpto/vpto_guarded_licm.pto: focused pass tests — basic, nestedscf.if, nested loops (innermost-first climbing), IV-dependent negative, non-speculatabledivsinegative.test/lit/vpto/vpto_guarded_licm_pipeline.pto: end-to-endpto.section.simt-> outlined helper -> VPTO pipeline regression checking the base chain is hoisted and the dynamic offset stays guarded.Validation
-Werror) on the validation host; fulltest/litsuite: 1830 passed, 0 failed (1 unsupported environment skip).llvm-lit.Review fixes
generic isPure() alone. A deterministic explicit allow-list (arith integer /
cast / compare / select / constant ops plus pto.addptr / pto.castptr /
pto.ptrtoint / pto.inttoptr) now gates hoisting, so referentially opaque
"pure" ops such as pto.get_clock32/64, pto.get_vms4_sr and
pto.vote_/pto.shuffle_/pto.redux_* stay inside the guard.
ceildivui are now explicitly excluded alongside divsi/divui/divf/remsi/remui/
remf, so zero-divisor or INT_MIN / -1 UB cannot be hoisted in front of the
guard.
compliance check reports 0 errors / 0 warnings.
arith.floordivsi.