[llvm] 7e14161 - [LoopPeel] Handle constants when updating exit values when peeling last.
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Sun May 18 02:17:46 PDT 2025
Author: Florian Hahn
Date: 2025-05-18T10:17:21+01:00
New Revision: 7e14161f49b32387988cf9d937bbfaa27d0fbdd5
URL: https://github.com/llvm/llvm-project/commit/7e14161f49b32387988cf9d937bbfaa27d0fbdd5
DIFF: https://github.com/llvm/llvm-project/commit/7e14161f49b32387988cf9d937bbfaa27d0fbdd5.diff
LOG: [LoopPeel] Handle constants when updating exit values when peeling last.
Account for constant values when updating exit values after peeling an
iteration from the end. This can happen if the inner loop gets unrolled
and simplified.
Fixes https://github.com/llvm/llvm-project/issues/140442.
Added:
llvm/test/Transforms/LoopUnroll/unroll-and-peel-last-iteration.ll
Modified:
llvm/lib/Transforms/Utils/LoopPeel.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Utils/LoopPeel.cpp b/llvm/lib/Transforms/Utils/LoopPeel.cpp
index c5c637ab6e202..646354bba9df6 100644
--- a/llvm/lib/Transforms/Utils/LoopPeel.cpp
+++ b/llvm/lib/Transforms/Utils/LoopPeel.cpp
@@ -1214,7 +1214,7 @@ bool llvm::peelLoop(Loop *L, unsigned PeelCount, bool PeelLast, LoopInfo *LI,
// Now adjust users of the original exit values by replacing them with the
// exit value from the peeled iteration.
for (const auto &[P, E] : ExitValues)
- P->replaceAllUsesWith(VMap.lookup(E));
+ P->replaceAllUsesWith(isa<Constant>(E) ? E : &*VMap.lookup(E));
formLCSSA(*L, DT, LI, SE);
} else {
// Now adjust the phi nodes in the loop header to get their initial values
diff --git a/llvm/test/Transforms/LoopUnroll/unroll-and-peel-last-iteration.ll b/llvm/test/Transforms/LoopUnroll/unroll-and-peel-last-iteration.ll
new file mode 100644
index 0000000000000..f57fb2d9b7057
--- /dev/null
+++ b/llvm/test/Transforms/LoopUnroll/unroll-and-peel-last-iteration.ll
@@ -0,0 +1,79 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -p loop-unroll -S %s | FileCheck %s
+
+; Test case for https://github.com/llvm/llvm-project/issues/140442.
+define i32 @peel_last_iter_of_outer_lcssa_phi_with_constant_after_unrolling_inner() {
+; CHECK-LABEL: define i32 @peel_last_iter_of_outer_lcssa_phi_with_constant_after_unrolling_inner() {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[OUTER_HEADER:.*]]
+; CHECK: [[OUTER_HEADER]]:
+; CHECK-NEXT: [[IV:%.*]] = phi i16 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[INNER_LATCH:.*]] ]
+; CHECK-NEXT: br label %[[INNER_HEADER:.*]]
+; CHECK: [[INNER_HEADER]]:
+; CHECK-NEXT: br i1 false, label %[[THEN:.*]], label %[[INNER_LATCH]]
+; CHECK: [[THEN]]:
+; CHECK-NEXT: call void @foo(i32 0)
+; CHECK-NEXT: br label %[[INNER_LATCH]]
+; CHECK: [[INNER_LATCH]]:
+; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i16 [[IV]], 1
+; CHECK-NEXT: [[EC:%.*]] = icmp eq i16 [[IV_NEXT]], 999
+; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_PEEL_BEGIN:.*]], label %[[OUTER_HEADER]], !llvm.loop [[LOOP0:![0-9]+]]
+; CHECK: [[EXIT_PEEL_BEGIN]]:
+; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i16 [ [[IV_NEXT]], %[[INNER_LATCH]] ]
+; CHECK-NEXT: [[DOTLCSSA_LCSSA:%.*]] = phi i32 [ 1, %[[INNER_LATCH]] ]
+; CHECK-NEXT: br label %[[OUTER_HEADER_PEEL:.*]]
+; CHECK: [[OUTER_HEADER_PEEL]]:
+; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i16 [[IV_NEXT_LCSSA]], 999
+; CHECK-NEXT: br label %[[INNER_HEADER_PEEL:.*]]
+; CHECK: [[INNER_HEADER_PEEL]]:
+; CHECK-NEXT: br i1 [[TMP0]], label %[[THEN_PEEL:.*]], label %[[INNER_LATCH_PEEL:.*]]
+; CHECK: [[THEN_PEEL]]:
+; CHECK-NEXT: call void @foo(i32 0)
+; CHECK-NEXT: br label %[[INNER_LATCH_PEEL]]
+; CHECK: [[INNER_LATCH_PEEL]]:
+; CHECK-NEXT: [[IV_NEXT_PEEL:%.*]] = add i16 [[IV_NEXT_LCSSA]], 1
+; CHECK-NEXT: [[EC_PEEL:%.*]] = icmp eq i16 [[IV_NEXT_PEEL]], 1000
+; CHECK-NEXT: br i1 [[EC_PEEL]], label %[[EXIT_PEEL_NEXT:.*]], label %[[EXIT_PEEL_NEXT]]
+; CHECK: [[EXIT_PEEL_NEXT]]:
+; CHECK-NEXT: br label %[[OUTER_HEADER_PEEL_NEXT:.*]]
+; CHECK: [[OUTER_HEADER_PEEL_NEXT]]:
+; CHECK-NEXT: br label %[[EXIT:.*]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret i32 1
+;
+entry:
+ br label %outer.header
+
+outer.header:
+ %iv = phi i16 [ 0, %entry ], [ %iv.next, %outer.latch ]
+ %0 = icmp eq i16 %iv, 999
+ br label %inner.header
+
+inner.header:
+ %inner.iv = phi i32 [ 0, %outer.header ], [ %inner.iv.next, %inner.latch ]
+ %1 = add i32 %inner.iv, 1
+ br i1 %0, label %then, label %inner.latch
+
+then:
+ call void @foo(i32 %inner.iv)
+ br label %inner.latch
+
+inner.latch:
+ %inner.iv.next = add i32 %inner.iv, 1
+ %inner.ec = icmp eq i32 %inner.iv.next, 1
+ br i1 %inner.ec, label %outer.latch, label %inner.header
+
+outer.latch:
+ %iv.next = add i16 %iv, 1
+ %ec = icmp eq i16 %iv.next, 1000
+ br i1 %ec, label %exit, label %outer.header
+
+exit:
+ ret i32 %1
+}
+
+declare void @foo(i32)
+;.
+; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]]}
+; CHECK: [[META1]] = !{!"llvm.loop.peeled.count", i32 1}
+;.
More information about the llvm-commits
mailing list