Skip to content

Commit a8e9742

Browse files
committed
[IndVarSimplify] Clear block and loop dispositions after moving instr.
Moving an instruction can invalidate the cached block dispositions of the corresponding SCEV. Invalidate the cached dispositions. Also fixes a copy-paste error in forgetBlockAndLoopDispositions where the start expression S was removed from BlockDispositions in the loop but not the current values. This was also exposed by the new test case. Fixes llvm#58439.
1 parent 6608908 commit a8e9742

File tree

3 files changed

+34
-5
lines changed

3 files changed

+34
-5
lines changed

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8408,9 +8408,10 @@ void ScalarEvolution::forgetBlockAndLoopDispositions(Value *V) {
84088408
SmallPtrSet<const SCEV *, 8> Seen = {S};
84098409
while (!Worklist.empty()) {
84108410
const SCEV *Curr = Worklist.pop_back_val();
8411-
if (!LoopDispositions.erase(Curr) && !BlockDispositions.erase(S))
8411+
bool LoopDispoRemoved = LoopDispositions.erase(Curr);
8412+
bool BlockDispoRemoved = BlockDispositions.erase(Curr);
8413+
if (!LoopDispoRemoved && !BlockDispoRemoved)
84128414
continue;
8413-
84148415
auto Users = SCEVUsers.find(Curr);
84158416
if (Users != SCEVUsers.end())
84168417
for (const auto *User : Users->second)

llvm/lib/Transforms/Scalar/IndVarSimplify.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,6 +1281,7 @@ bool IndVarSimplify::sinkUnusedInvariants(Loop *L) {
12811281

12821282
MadeAnyChanges = true;
12831283
ToMove->moveBefore(*ExitBlock, InsertPt);
1284+
SE->forgetBlockAndLoopDispositions(ToMove);
12841285
if (Done) break;
12851286
InsertPt = ToMove->getIterator();
12861287
}

llvm/test/Transforms/IndVarSimplify/pr54434.ll renamed to llvm/test/Transforms/IndVarSimplify/scev-invalidation.ll

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2-
; RUN: opt -S -indvars -verify-scev < %s | FileCheck %s
2+
; RUN: opt -S -passes=indvars -verify-scev < %s | FileCheck %s
33

4-
define void @test() {
5-
; CHECK-LABEL: @test(
4+
define void @test_pr54434() {
5+
; CHECK-LABEL: @test_pr54434(
66
; CHECK-NEXT: entry:
77
; CHECK-NEXT: br label [[FOR_COND:%.*]]
88
; CHECK: for.cond:
@@ -43,3 +43,30 @@ for.end106: ; preds = %for.cond
4343
ret void
4444
}
4545

46+
define i32 @test_pr58439(i32 %a) {
47+
; CHECK-LABEL: @test_pr58439(
48+
; CHECK-NEXT: entry:
49+
; CHECK-NEXT: br label [[LOOP:%.*]]
50+
; CHECK: loop:
51+
; CHECK-NEXT: br i1 false, label [[LOOP]], label [[EXIT:%.*]]
52+
; CHECK: exit:
53+
; CHECK-NEXT: [[C_EXT_LCSSA:%.*]] = phi i32 [ 0, [[LOOP]] ]
54+
; CHECK-NEXT: [[OR:%.*]] = or i32 [[A:%.*]], 1
55+
; CHECK-NEXT: [[RES:%.*]] = add i32 [[C_EXT_LCSSA]], [[OR]]
56+
; CHECK-NEXT: ret i32 [[RES]]
57+
;
58+
entry:
59+
%or = or i32 %a, 1
60+
br label %loop
61+
62+
loop:
63+
%iv = phi i32 [ 1, %entry ], [ %iv.next, %loop ]
64+
%iv.next = add i32 %iv, 1
65+
%c.1 = icmp eq i32 %iv.next, %or
66+
%c.ext = zext i1 %c.1 to i32
67+
br i1 false, label %loop, label %exit
68+
69+
exit:
70+
%res = add i32 %c.ext, %or
71+
ret i32 %res
72+
}

0 commit comments

Comments
 (0)