[AIE] Fix findPrologueEpilogue assert on loops with multiple non-loop preds#1005
Merged
martien-de-jong merged 1 commit intoMay 19, 2026
Merged
Conversation
… preds Single-MBB loops with multiple non-loop predecessors are legal (e.g. do-while style outer loops, or halt-spin self-edges combined with an end-of-iteration backedge from a separate cleanup block). The pipeliner's PipelineExtractor was historically the only caller of this code, and pipelining filters guarantee a unique prologue/epilogue -- so the asserts were safe in that context. After the helper was extracted in 5fbf293 and reused from emitLoopRemarks in 007425c (which runs on every single-MBB loop, pipelined or not), the assertion began firing on legitimate code. Make findPrologueEpilogue return nullptr for the ambiguous side instead of asserting. The pipeliner call site keeps its own assert(PrologueMBB && EpilogueMBB ...) so pipelined code that ever violated the invariant still fires loudly. The remark emitter already had a nullptr guard.
Contributor
Author
|
Cc: @F-Stuckmann |
2 tasks
erwei-xilinx
added a commit
to Xilinx/mlir-air
that referenced
this pull request
May 19, 2026
…llvm-aie#1005 lands) (#1617) Nightly llvm-aie 2026-05-16 onwards (commit 55604435 and later) crash llc on legitimate non-pipelined single-MBB loops via an assert in AIELoopUtils::findPrologueEpilogue, blocking 9+ Ryzen AI xrt tests on both NPU Phoenix and NPU Strix. Pin to the last known-good nightly (2026-05-15, f4933ef7) in both the Ryzen AI CI workflow and the developer wheel-install script until the upstream fix lands. See Xilinx/llvm-aie#1005 for the root cause and fix. Revert this commit once a clean llvm-aie nightly is published. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
martien-de-jong
approved these changes
May 19, 2026
Collaborator
|
Thanks for fixing this. |
1 task
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.
Summary
Fix
llcassertion failure on legitimate non-pipelined single-MBB loops whose loop header has multiple non-loop predecessors.AIELoopUtils::findPrologueEpilogue(introduced in 5fbf293) asserted that a single-MBB loop has at most one non-loop predecessor / successor. That invariant only holds for pipelined loops, which was fine when the only caller wasPipelineExtractor's constructor (gated by pipelining filters that guarantee uniqueness).007425c ("[AIEX] Emit unified pipeliner optimization remarks for all loop types") added a second caller in
InterBlockScheduling::emitLoopRemarksthat runs on every single-MBB loop, pipelined or not. Non-pipelined loops can legitimately have multiple non-loop predecessors — e.g. an outerdo-whileloop reached both from a function-entry block and from an end-of-iteration cleanup block, or a halt-spin self-edge combined with normal entry paths. So the assertion now fires on legal CFGs.Fix
Make
findPrologueEpiloguereturnnullptrfor the ambiguous side instead of asserting. The remark-emitter call site already hasif (!PrologueMBB || !EpilogueMBB) continue;. The pipeliner call site keeps its ownassert(PrologueMBB && EpilogueMBB && "Pipelined loop must have a unique prologue and epilogue"), so pipelined code that ever violates the invariant still fails loudly at the only site where it actually matters.Crash signature
Impact
Currently blocking the mlir-air Ryzen AI CI on both NPU Phoenix (amd8845hs, npu1) and NPU Strix (amdhx370, npu2) runners. Reference failing run: Xilinx/mlir-air actions run 26049388494.
NPU Phoenix (npu1) — 9 failing tests:
xrt/02_mul_shim_1x1/run_peano.litxrt/03_mul_L1L2_1x1/run_peano.litxrt/06_add_shim_bf16/run_peano.litxrt/07_extern_linalg/run_npu1_peano.litxrt/28_gemm_loop_nest_bf16/run_peano.litxrt/29_gemm_4_level_tiling_extern_vec_4x4_bf16/run_peano.litxrt/34_cascade_vecadd/run_npu1_peano.litxrt/36_cascade_vecmat_i32/run_npu1_peano.litxrt/38_cascade_vecmat_transform_2x4_i32/run_npu1_peano.litNPU Strix (npu2) — 11 failing tests (superset of the npu1 list with
_npu2_peanovariants, plus 2 npu2-only tests:03_mul_L1L2_1x1/run_peano_elf.litand30_mul_rtp_1x1/run_npu2_peano.lit).All 9 npu1 tests verified to pass on real NPU Phoenix hardware with this patch applied to nightly
21.0.0.2026051801+55604435. The npu2 failures share the same root cause (same llc binary, samefindPrologueEpilogueassertion in the same crash stack), so the fix should unblock them as well.Bisect
2026051501+f4933ef7(May 15)2026051601+55604435(May 16)Test
Added
llvm/test/CodeGen/AIE/aie2/schedule/postpipeliner/loop-remark-multi-pred.mir: minimal MIR with a single-MBB loop reached from two non-loop predecessors (function entry and end-of-iteration cleanup). Verified to fail onaie-publicHEAD without the fix and pass with it.