[llvm-branch-commits] [llvm] f54355e - [LoopUnroll] Invalidate SCEV after full unrolling (#208874)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Jul 16 09:26:03 PDT 2026
Author: 陈子昂
Date: 2026-07-16T08:00:41Z
New Revision: f54355e08d91e1f4c87337505936e9299a9ffb99
URL: https://github.com/llvm/llvm-project/commit/f54355e08d91e1f4c87337505936e9299a9ffb99
DIFF: https://github.com/llvm/llvm-project/commit/f54355e08d91e1f4c87337505936e9299a9ffb99.diff
LOG: [LoopUnroll] Invalidate SCEV after full unrolling (#208874)
Full unrolling may leave stale ScalarEvolution loop and disposition
caches around the loop pass boundary. A later IndVars pass can then use
stale exit count information and incorrectly fold reachable exits.
Invalidate SCEV loop and disposition caches after successful full
unrolling before preserving `ScalarEvolutionAnalysis.`
Fixes #207744.
(cherry picked from commit 42c2980c7c632d7a45776d3e2c51627100f6e763)
Added:
llvm/test/Transforms/LoopUnroll/full-unroll-scev-invalidation.ll
Modified:
llvm/lib/Transforms/Utils/LoopUnroll.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Utils/LoopUnroll.cpp b/llvm/lib/Transforms/Utils/LoopUnroll.cpp
index d00de52e1cb0b..1f9f340a9cb31 100644
--- a/llvm/lib/Transforms/Utils/LoopUnroll.cpp
+++ b/llvm/lib/Transforms/Utils/LoopUnroll.cpp
@@ -1284,6 +1284,10 @@ llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
// Loop over the PHI nodes in the original block, setting incoming values.
for (PHINode *PN : OrigPHINode) {
if (CompletelyUnroll) {
+ // The RAUW below disconnects the original PHI from its users.
+ // Invalidate cached SCEVs while the def-use chain is still intact.
+ if (SE)
+ SE->forgetValue(PN);
PN->replaceAllUsesWith(PN->getIncomingValueForBlock(Preheader));
PN->eraseFromParent();
} else if (ULO.Count > 1) {
diff --git a/llvm/test/Transforms/LoopUnroll/full-unroll-scev-invalidation.ll b/llvm/test/Transforms/LoopUnroll/full-unroll-scev-invalidation.ll
new file mode 100644
index 0000000000000..a9f7a1df0328a
--- /dev/null
+++ b/llvm/test/Transforms/LoopUnroll/full-unroll-scev-invalidation.ll
@@ -0,0 +1,55 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S -passes='loop(indvars,loop-unroll-full)' %s | FileCheck %s
+
+ at __chk = external global i64
+
+define void @f4(i64 %0) {
+; CHECK-LABEL: define void @f4(
+; CHECK-SAME: i64 [[TMP0:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[LBL_B5:.*]]
+; CHECK: [[LBL_B5]]:
+; CHECK-NEXT: br label %[[LBL_B10:.*]]
+; CHECK: [[LBL_B10]]:
+; CHECK-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP0]] to i32
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.ctpop.i32(i32 [[CONV1]])
+; CHECK-NEXT: [[TOBOOL4_NOT:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: br i1 [[TOBOOL4_NOT]], label %[[COMMON_RET1:.*]], label %[[IF_THEN8:.*]]
+; CHECK: [[IF_THEN8]]:
+; CHECK-NEXT: store i64 5, ptr @__chk, align 4
+; CHECK-NEXT: ret void
+; CHECK: [[COMMON_RET1]]:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %lbl_b5
+
+lbl_b5:
+ br label %lbl_b10
+
+lbl_b10:
+ %1 = phi i8 [ 0, %lbl_b5 ], [ 1, %lbl_b10 ]
+ %2 = phi i64 [ %0, %lbl_b5 ], [ 0, %lbl_b10 ]
+ %bb13.1 = phi i32 [ 0, %lbl_b5 ], [ %3, %lbl_b10 ]
+ %conv1 = trunc i64 %2 to i32
+ %3 = call i32 @llvm.ctpop.i32(i32 %conv1)
+ %loadedv = trunc i8 %1 to i1
+ br i1 %loadedv, label %if.then3, label %lbl_b10
+
+if.then3:
+ %tobool4.not = icmp eq i32 %bb13.1, 0
+ br i1 %tobool4.not, label %common.ret, label %if.then8
+
+if.then8:
+ br i1 true, label %if.then10, label %lbl_b5
+
+common.ret:
+ ret void
+
+if.then10:
+ %.lcssa.lcssa34 = phi i32 [ %3, %if.then8 ]
+ store i64 5, ptr @__chk
+ ret void
+}
+
+declare i32 @llvm.ctpop.i32(i32)
More information about the llvm-branch-commits
mailing list