Skip to content

Commit 9a456b7

Browse files
committed
[IndVars] Forget SCEV for replaced PHI.
Additional SCEV verification highlighted a case where the cached loop dispositions where incorrect after simplifying a phi node in IndVars. Fix it by invalidating the phi before replacing it. Fixes #58750
1 parent 1186e9d commit 9a456b7

File tree

2 files changed

+57
-3
lines changed

2 files changed

+57
-3
lines changed

llvm/lib/Transforms/Scalar/IndVarSimplify.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1308,7 +1308,8 @@ static void foldExit(const Loop *L, BasicBlock *ExitingBB, bool IsTaken,
13081308
}
13091309

13101310
static void replaceLoopPHINodesWithPreheaderValues(
1311-
LoopInfo *LI, Loop *L, SmallVectorImpl<WeakTrackingVH> &DeadInsts) {
1311+
LoopInfo *LI, Loop *L, SmallVectorImpl<WeakTrackingVH> &DeadInsts,
1312+
ScalarEvolution &SE) {
13121313
assert(L->isLoopSimplifyForm() && "Should only do it in simplify form!");
13131314
auto *LoopPreheader = L->getLoopPreheader();
13141315
auto *LoopHeader = L->getHeader();
@@ -1317,6 +1318,7 @@ static void replaceLoopPHINodesWithPreheaderValues(
13171318
auto *PreheaderIncoming = PN.getIncomingValueForBlock(LoopPreheader);
13181319
for (User *U : PN.users())
13191320
Worklist.push_back(cast<Instruction>(U));
1321+
SE.forgetValue(&PN);
13201322
PN.replaceAllUsesWith(PreheaderIncoming);
13211323
DeadInsts.emplace_back(&PN);
13221324
}
@@ -1588,7 +1590,7 @@ bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) {
15881590
// unconditional exit, we can still replace header phis with their
15891591
// preheader value.
15901592
if (!L->contains(BI->getSuccessor(CI->isNullValue())))
1591-
replaceLoopPHINodesWithPreheaderValues(LI, L, DeadInsts);
1593+
replaceLoopPHINodesWithPreheaderValues(LI, L, DeadInsts, *SE);
15921594
return true;
15931595
}
15941596

@@ -1675,7 +1677,7 @@ bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) {
16751677
// the header PHIs with values coming from the preheader.
16761678
if (ExitCount->isZero()) {
16771679
foldExit(L, ExitingBB, true, DeadInsts);
1678-
replaceLoopPHINodesWithPreheaderValues(LI, L, DeadInsts);
1680+
replaceLoopPHINodesWithPreheaderValues(LI, L, DeadInsts, *SE);
16791681
Changed = true;
16801682
continue;
16811683
}

llvm/test/Transforms/IndVarSimplify/invalidate-modified-lcssa-phi.ll

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,55 @@ exit:
156156
%lcssa = phi i16 [ %sum.next, %loop ]
157157
ret i16 0
158158
}
159+
160+
define i32 @pr58750(i16 %a, ptr %dst, i1 %c.0) {
161+
; CHECK-LABEL: @pr58750(
162+
; CHECK-NEXT: entry:
163+
; CHECK-NEXT: [[CMP186_NOT:%.*]] = icmp eq i16 [[A:%.*]], 0
164+
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP186_NOT]])
165+
; CHECK-NEXT: br label [[OUTER_HEADER:%.*]]
166+
; CHECK: outer.header:
167+
; CHECK-NEXT: [[P_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LCSSA:%.*]], [[OUTER_LATCH:%.*]] ]
168+
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[P_0]], 0
169+
; CHECK-NEXT: br label [[INNER:%.*]]
170+
; CHECK: inner:
171+
; CHECK-NEXT: store i16 0, ptr [[DST:%.*]], align 1
172+
; CHECK-NEXT: br i1 false, label [[INNER]], label [[OUTER_LATCH]]
173+
; CHECK: outer.latch:
174+
; CHECK-NEXT: [[LCSSA]] = phi i32 [ [[XOR]], [[INNER]] ]
175+
; CHECK-NEXT: br i1 [[C_0:%.*]], label [[OUTER_HEADER]], label [[EXIT:%.*]]
176+
; CHECK: exit:
177+
; CHECK-NEXT: [[LCSSA_LCSSA:%.*]] = phi i32 [ [[LCSSA]], [[OUTER_LATCH]] ]
178+
; CHECK-NEXT: ret i32 [[LCSSA_LCSSA]]
179+
;
180+
entry:
181+
%cmp186.not = icmp eq i16 %a, 0
182+
call void @llvm.assume(i1 %cmp186.not)
183+
br label %outer.header
184+
185+
outer.header:
186+
%p.0 = phi i32 [ 0, %entry ], [ %lcssa, %outer.latch ]
187+
br label %inner
188+
189+
inner:
190+
%inner.iv = phi i16 [ 0, %outer.header ], [ %inner.iv.next, %inner ]
191+
%p.1 = phi i32 [ %p.0, %outer.header ], [ %xor, %inner ]
192+
store i16 %inner.iv, ptr %dst, align 1
193+
%conv = sext i16 %inner.iv to i32
194+
%xor = xor i32 %p.1, %conv
195+
%inner.iv.next = add nuw i16 %inner.iv, 1
196+
%c.1 = icmp ult i16 %inner.iv.next, %a
197+
br i1 %c.1, label %inner, label %outer.latch
198+
199+
outer.latch:
200+
%lcssa = phi i32 [ %xor, %inner ]
201+
br i1 %c.0, label %outer.header, label %exit
202+
203+
exit:
204+
ret i32 %lcssa
205+
}
206+
207+
; Function Attrs: inaccessiblememonly nocallback nofree nosync nounwind willreturn
208+
declare void @llvm.assume(i1 noundef) #1
209+
210+

0 commit comments

Comments
 (0)