diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp --- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp +++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp @@ -1470,6 +1470,13 @@ PHINode *NewPhi = dyn_cast(P.clone()); NewPhi->setIncomingValue(0, P.getIncomingValue(0)); NewPhi->setIncomingBlock(0, OuterLatch); + // We might have incoming edges from other BBs, i.e., the original outer + // header. + for (auto *Pred : predecessors(InnerLatch)) { + if (Pred == OuterLatch) + continue; + NewPhi->addIncoming(P.getIncomingValue(0), Pred); + } NewPhi->insertBefore(InnerLatch->getFirstNonPHI()); P.setIncomingValue(0, NewPhi); } diff --git a/llvm/test/Transforms/LoopInterchange/lcssa.ll b/llvm/test/Transforms/LoopInterchange/lcssa.ll --- a/llvm/test/Transforms/LoopInterchange/lcssa.ll +++ b/llvm/test/Transforms/LoopInterchange/lcssa.ll @@ -298,3 +298,35 @@ for.end16: ; preds = %for.exit ret void } + +; Should not crash when the outer header branches to +; both the inner loop and the outer latch, and there +; is an lcssa phi node outside the loopnest. +; REMARK: Interchanged +; REMARK-NEXT: lcssa_08 +define i64 @lcssa_08([100 x [100 x i64]]* %Arr) { +entry: + br label %for1.header + +for1.header: ; preds = %for1.inc, %entry + %indvars.iv23 = phi i64 [ 0, %entry ], [ %indvars.iv.next24, %for1.inc ] + br i1 undef, label %for2, label %for1.inc + +for2: ; preds = %for2, %for1.header + %indvars.iv = phi i64 [ 0, %for1.header ], [ %indvars.iv.next.3, %for2 ] + %arrayidx = getelementptr inbounds [100 x [100 x i64]], [100 x [100 x i64]]* %Arr, i64 0, i64 %indvars.iv, i64 %indvars.iv23 + %lv = load i64, i64* %arrayidx, align 4 + %indvars.iv.next.3 = add nuw nsw i64 %indvars.iv, 1 + %exit1 = icmp eq i64 %indvars.iv.next.3, 100 + br i1 %exit1, label %for1.inc, label %for2 + +for1.inc: ; preds = %for2, %for1.header + %indvars.iv.next24 = add nuw nsw i64 %indvars.iv23, 1 + %exit2 = icmp eq i64 %indvars.iv.next24, 100 + br i1 %exit2, label %for1.loopexit, label %for1.header + +for1.loopexit: ; preds = %for1.inc + %sum.outer.lcssa = phi i64 [ %indvars.iv23, %for1.inc ] + ret i64 %sum.outer.lcssa +} +