[llvm] [loop-idiom] Forget outer loop scev when loop-idiom introduces memset… (PR #150916)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 28 03:05:29 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Sushant Gokhale (sushgokh)
<details>
<summary>Changes</summary>
… in the outer loop
Before loop-idiom pass, we have a store into the inner loop which is considered simple and one that does not have any side effects on the loop. Post loop-idiom pass, we get a memset into the outer loop that is considered to introduce side effects on the loop. This changes the backedge taken count before and after the pass and hence, the crash with verify-scev.
Ideally, I would expect store to be considered as an instruction that introduces side effects like the memset but this generates lot of test failures.
Fixes #<!-- -->149377
---
Full diff: https://github.com/llvm/llvm-project/pull/150916.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (+5)
- (added) llvm/test/Transforms/LoopIdiom/AArch64/introduce-memset-in-outerloop.ll (+48)
``````````diff
diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index 03b92d3338a98..7cee8a7525c42 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -1154,6 +1154,11 @@ bool LoopIdiomRecognize::processLoopStridedStore(
NewCall->setDebugLoc(TheStore->getDebugLoc());
+ auto *MemsetLoop = LI->getLoopFor(NewCall->getParent());
+ // FIXME: We should invalidate scev only if the loop already does not have any
+ // side effects.
+ SE->forgetLoop(MemsetLoop);
+
if (MSSAU) {
MemoryAccess *NewMemAcc = MSSAU->createMemoryAccessInBB(
NewCall, nullptr, NewCall->getParent(), MemorySSA::BeforeTerminator);
diff --git a/llvm/test/Transforms/LoopIdiom/AArch64/introduce-memset-in-outerloop.ll b/llvm/test/Transforms/LoopIdiom/AArch64/introduce-memset-in-outerloop.ll
new file mode 100644
index 0000000000000..924db26cd573e
--- /dev/null
+++ b/llvm/test/Transforms/LoopIdiom/AArch64/introduce-memset-in-outerloop.ll
@@ -0,0 +1,48 @@
+; REQUIRES: asserts
+; RUN: opt <%s -p "loop(loop-idiom)" -verify-scev -o /dev/null
+
+
+; IR corresponds to the following C test:
+; extern char a[];
+; void foo() {
+; for (long c = 0; c < 6; c += -2078836808675943215)
+; for (long d; d < 6; d++)
+; a[c + d] = 0;
+; }
+
+; Make sure we do not crash when verifying scev.
+
+ at a = external global [0 x i8]
+
+define void @foo() {
+entry:
+ br label %outerL
+
+outerL: ; preds = %entry, %outerLatch
+ %e = phi i64 [ undef, %entry ], [ %lcssa, %outerLatch ]
+ %c = phi i64 [ 0, %entry ], [ %c.next, %outerLatch ]
+ %e.cmp = icmp slt i64 %e, 6
+ br i1 %e.cmp, label %innerL, label %outerLatch
+
+innerL: ; preds = %outerL, %innerL
+ %d = phi i64 [ %d.next, %innerL ], [ %e, %outerL ]
+ %add = add nsw i64 %d, %c
+ %arrayidx = getelementptr inbounds [0 x i8], ptr @a, i64 0, i64 %add
+ store i8 0, ptr %arrayidx
+ %d.next = add nsw i64 %d, 1
+ %d.cmp = icmp slt i64 %d, 5
+ br i1 %d.cmp, label %innerL, label %outerLatch, !llvm.loop !0
+
+outerLatch: ; preds = %innerL, %outerL
+ %lcssa = phi i64 [ %e, %outerL ], [ %d.next, %innerL ]
+ %c.next = add nsw i64 %c, -2078836808675943215
+ %c.cmp = icmp slt i64 %c, 2078836808675943221
+ br i1 %c.cmp, label %outerL, label %exit, !llvm.loop !1
+
+exit: ; preds = %outerLatch
+ ret void
+}
+
+!0 = distinct !{!0, !2}
+!1 = distinct !{!1, !2}
+!2 = !{!"llvm.loop.mustprogress"}
``````````
</details>
https://github.com/llvm/llvm-project/pull/150916
More information about the llvm-commits
mailing list