Skip to content

Commit 3f8be15

Browse files
[LoopInterchange] Handle lcssa PHIs with multiple predecessors
This is a bugfix in the transformation phase. If the original outer loop header branches to both the inner loop (header) and the outer loop latch, and if there is an lcssa PHI node outside the loop nest, then after interchange the new outer latch will have an lcssa PHI node inserted which has two predecessors, i.e., the original outer header and the original outer latch. Currently the transformation assumes it has only one predecessor (the original outer latch) and crashes, since the inserted lcssa PHI node does not take both predecessors as incoming BBs. Reviewed By: Whitney Differential Revision: https://reviews.llvm.org/D100792
1 parent 10c309a commit 3f8be15

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

llvm/lib/Transforms/Scalar/LoopInterchange.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1529,6 +1529,13 @@ static void moveLCSSAPhis(BasicBlock *InnerExit, BasicBlock *InnerHeader,
15291529
PHINode *NewPhi = dyn_cast<PHINode>(P.clone());
15301530
NewPhi->setIncomingValue(0, P.getIncomingValue(0));
15311531
NewPhi->setIncomingBlock(0, OuterLatch);
1532+
// We might have incoming edges from other BBs, i.e., the original outer
1533+
// header.
1534+
for (auto *Pred : predecessors(InnerLatch)) {
1535+
if (Pred == OuterLatch)
1536+
continue;
1537+
NewPhi->addIncoming(P.getIncomingValue(0), Pred);
1538+
}
15321539
NewPhi->insertBefore(InnerLatch->getFirstNonPHI());
15331540
P.setIncomingValue(0, NewPhi);
15341541
}

llvm/test/Transforms/LoopInterchange/lcssa.ll

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,3 +298,35 @@ for.exit: ; preds = %outer.inc
298298
for.end16: ; preds = %for.exit
299299
ret void
300300
}
301+
302+
; Should not crash when the outer header branches to
303+
; both the inner loop and the outer latch, and there
304+
; is an lcssa phi node outside the loopnest.
305+
; REMARK: Interchanged
306+
; REMARK-NEXT: lcssa_08
307+
define i64 @lcssa_08([100 x [100 x i64]]* %Arr) {
308+
entry:
309+
br label %for1.header
310+
311+
for1.header: ; preds = %for1.inc, %entry
312+
%indvars.iv23 = phi i64 [ 0, %entry ], [ %indvars.iv.next24, %for1.inc ]
313+
br i1 undef, label %for2, label %for1.inc
314+
315+
for2: ; preds = %for2, %for1.header
316+
%indvars.iv = phi i64 [ 0, %for1.header ], [ %indvars.iv.next.3, %for2 ]
317+
%arrayidx = getelementptr inbounds [100 x [100 x i64]], [100 x [100 x i64]]* %Arr, i64 0, i64 %indvars.iv, i64 %indvars.iv23
318+
%lv = load i64, i64* %arrayidx, align 4
319+
%indvars.iv.next.3 = add nuw nsw i64 %indvars.iv, 1
320+
%exit1 = icmp eq i64 %indvars.iv.next.3, 100
321+
br i1 %exit1, label %for1.inc, label %for2
322+
323+
for1.inc: ; preds = %for2, %for1.header
324+
%indvars.iv.next24 = add nuw nsw i64 %indvars.iv23, 1
325+
%exit2 = icmp eq i64 %indvars.iv.next24, 100
326+
br i1 %exit2, label %for1.loopexit, label %for1.header
327+
328+
for1.loopexit: ; preds = %for1.inc
329+
%sum.outer.lcssa = phi i64 [ %indvars.iv23, %for1.inc ]
330+
ret i64 %sum.outer.lcssa
331+
}
332+

0 commit comments

Comments
 (0)