[llvm-branch-commits] [llvm] release/23.x: [LoopUnroll] Invalidate SCEV after full unrolling (#208874) (PR #210003)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Jul 16 01:01:49 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: llvmbot
<details>
<summary>Changes</summary>
Backport 42c2980c7c632d7a45776d3e2c51627100f6e763
Requested by: @<!-- -->nikic
---
Full diff: https://github.com/llvm/llvm-project/pull/210003.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/Utils/LoopUnroll.cpp (+4)
- (added) llvm/test/Transforms/LoopUnroll/full-unroll-scev-invalidation.ll (+55)
``````````diff
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)
``````````
</details>
https://github.com/llvm/llvm-project/pull/210003
More information about the llvm-branch-commits
mailing list