Skip to content

Commit e8918c3

Browse files
authored
[SCEV] Consider non-volatile memory intrinsics as not having side-effect for forward progress (#150916)
For the attached test: Before the 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. We try to consider non-volatile memory intrinsics as not having side-effect for forward progress to fix the issue. Fixes #149377
1 parent e92b7e9 commit e8918c3

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7435,7 +7435,15 @@ ScalarEvolution::getLoopProperties(const Loop *L) {
74357435
if (auto *SI = dyn_cast<StoreInst>(I))
74367436
return !SI->isSimple();
74377437

7438-
return I->mayThrow() || I->mayWriteToMemory();
7438+
if (I->mayThrow())
7439+
return true;
7440+
7441+
// Non-volatile memset / memcpy do not count as side-effect for forward
7442+
// progress.
7443+
if (isa<MemIntrinsic>(I) && !I->isVolatile())
7444+
return false;
7445+
7446+
return I->mayWriteToMemory();
74397447
};
74407448

74417449
LoopProperties LP = {/* HasNoAbnormalExits */ true,
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
; RUN: opt <%s -p "print<scalar-evolution>" -disable-output 2>&1 | FileCheck %s
2+
; RUN: opt <%s -p "loop(loop-idiom),print<scalar-evolution>" -disable-output 2>&1 | FileCheck %s
3+
4+
; CHECK: backedge-taken count is i64 1
5+
6+
; IR corresponds to the following C test:
7+
; extern char a[];
8+
; void foo() {
9+
; for (long c = 0; c < 6; c += -2078836808675943215)
10+
; for (long d; d < 6; d++)
11+
; a[c + d] = 0;
12+
; }
13+
14+
@a = external global [0 x i8]
15+
16+
define void @foo() {
17+
entry:
18+
br label %outerL
19+
20+
outerL: ; preds = %entry, %outerLatch
21+
%e = phi i64 [ poison, %entry ], [ %lcssa, %outerLatch ]
22+
%c = phi i64 [ 0, %entry ], [ %c.next, %outerLatch ]
23+
%e.cmp = icmp slt i64 %e, 6
24+
br i1 %e.cmp, label %innerL, label %outerLatch
25+
26+
innerL: ; preds = %outerL, %innerL
27+
%d = phi i64 [ %d.next, %innerL ], [ %e, %outerL ]
28+
%add = add nsw i64 %d, %c
29+
%arrayidx = getelementptr inbounds [0 x i8], ptr @a, i64 0, i64 %add
30+
store i8 0, ptr %arrayidx
31+
%d.next = add nsw i64 %d, 1
32+
%d.cmp = icmp slt i64 %d, 5
33+
br i1 %d.cmp, label %innerL, label %outerLatch, !llvm.loop !0
34+
35+
outerLatch: ; preds = %innerL, %outerL
36+
%lcssa = phi i64 [ %e, %outerL ], [ %d.next, %innerL ]
37+
%c.next = add nsw i64 %c, -2078836808675943215
38+
%c.cmp = icmp slt i64 %c, 2078836808675943221
39+
br i1 %c.cmp, label %outerL, label %exit, !llvm.loop !1
40+
41+
exit: ; preds = %outerLatch
42+
ret void
43+
}
44+
45+
!0 = distinct !{!0, !2}
46+
!1 = distinct !{!1, !2}
47+
!2 = !{!"llvm.loop.mustprogress"}

0 commit comments

Comments
 (0)