From f7f0fd24c5df8084b27bce0350120f8765560f98 Mon Sep 17 00:00:00 2001 From: "cervol@DESKTOP-wsl2" Date: Sun, 26 Apr 2026 22:00:07 +0800 Subject: [PATCH 1/3] Fix nested loop unroll exit value repair --- ir/function.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ir/function.cpp b/ir/function.cpp index e4107b7a4..8d820efff 100644 --- a/ir/function.cpp +++ b/ir/function.cpp @@ -608,10 +608,6 @@ void Function::unroll(unsigned k) { // computed bottom-up during the post-order traversal below unordered_map> loop_nodes; - // grab all value users before duplication so the list is shorter - auto users = getUsers(); - auto phi_preds = getPhiPredecessors(*this); - // traverse each loop tree in post-order while (!worklist.empty()) { auto [header, height, flag] = worklist.back(); @@ -644,6 +640,12 @@ void Function::unroll(unsigned k) { } } + // Grab value users before duplicating the current loop so the list stays + // shorter. This must be refreshed per loop because unrolling an inner loop + // can introduce phis that outer-loop exits now use. + auto users = getUsers(); + auto phi_preds = getPhiPredecessors(*this); + // map: original BB -> {BB} U copies-of-BB unordered_map> bbmap; for (auto *bb : loop_bbs) { @@ -1237,4 +1239,3 @@ void LoopAnalysis::printDot(ostream &os) const { } } - From 1a5994cc4613ddc81bee843fac065e42211c7ebd Mon Sep 17 00:00:00 2001 From: "cervol@DESKTOP-wsl2" Date: Sun, 26 Apr 2026 22:00:12 +0800 Subject: [PATCH 2/3] Add nested loop unroll exit phi test --- .../alive-tv/loops/nested-exit-phi.srctgt.ll | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 tests/alive-tv/loops/nested-exit-phi.srctgt.ll diff --git a/tests/alive-tv/loops/nested-exit-phi.srctgt.ll b/tests/alive-tv/loops/nested-exit-phi.srctgt.ll new file mode 100644 index 000000000..fa2e86f08 --- /dev/null +++ b/tests/alive-tv/loops/nested-exit-phi.srctgt.ll @@ -0,0 +1,27 @@ +; TEST-ARGS: -src-unroll=2 -tgt-unroll=2 + +define i32 @src() { + br label %1 + +1: + %2 = phi i32 [ 0, %0 ], [ 1, %6 ] + br label %3 + +3: + %4 = mul i32 %2, 1 + br label %5 + +5: + br i1 false, label %3, label %6 + +6: + %7 = icmp slt i32 %2, 1 + br i1 %7, label %1, label %8 + +8: + ret i32 %4 +} + +define i32 @tgt() { + ret i32 1 +} From d20065f8a63ac295fb21f5077248f60fcfc136f7 Mon Sep 17 00:00:00 2001 From: Cervol Liu Date: Sun, 26 Apr 2026 22:14:23 +0800 Subject: [PATCH 3/3] Update ir/function.cpp Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- ir/function.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ir/function.cpp b/ir/function.cpp index 8d820efff..81a97eb8e 100644 --- a/ir/function.cpp +++ b/ir/function.cpp @@ -1238,4 +1238,4 @@ void LoopAnalysis::printDot(ostream &os) const { os << "}\n"; } -} +}