Index: lib/Transforms/Utils/LoopUnroll.cpp =================================================================== --- lib/Transforms/Utils/LoopUnroll.cpp +++ lib/Transforms/Utils/LoopUnroll.cpp @@ -256,7 +256,9 @@ // Are we eliminating the loop control altogether? bool CompletelyUnroll = Count == TripCount; SmallVector ExitBlocks; + SmallVector ExitingBlocks; L->getExitBlocks(ExitBlocks); + L->getExitingBlocks(ExitingBlocks); // Go through all exits of L and see if there are any phi-nodes there. We just // conservatively assume that they're inserted to preserve LCSSA form, which @@ -554,11 +556,17 @@ // the previous idom and the first latch, which dominates all copies of the // exiting block. if (DT && Count > 1) { - for (auto Exit : ExitBlocks) { - BasicBlock *PrevIDom = DT->getNode(Exit)->getIDom()->getBlock(); - BasicBlock *NewIDom = - DT->findNearestCommonDominator(PrevIDom, Latches[0]); - DT->changeImmediateDominator(Exit, NewIDom); + for (auto BB : ExitingBlocks) { + auto *BBDomNode = DT->getNode(BB); + for (auto *ChildDomNode : BBDomNode->getChildren()) { + auto ChildBB = ChildDomNode->getBlock(); + if (L->contains(ChildBB)) + continue; + BasicBlock *PrevIDom = ChildDomNode->getIDom()->getBlock(); + BasicBlock *NewIDom = + DT->findNearestCommonDominator(PrevIDom, Latches[0]); + DT->changeImmediateDominator(ChildBB, NewIDom); + } } } Index: test/Transforms/LoopUnroll/pr27157.ll =================================================================== --- /dev/null +++ test/Transforms/LoopUnroll/pr27157.ll @@ -0,0 +1,30 @@ +; RUN: opt -loop-unroll -debug-only=loop-unroll -disable-output < %s +; REQUIRES: asserts +; Compile this test with debug flag on to verify domtree right after loop unrolling. +target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64" + +; PR27157 +define void @foo() { +entry: + br label %loop_header +loop_header: + %iv = phi i64 [ 0, %entry ], [ %iv_next, %loop_latch ] + br i1 undef, label %loop_latch, label %loop_exiting_bb1 +loop_exiting_bb1: + br i1 false, label %loop_exiting_bb2, label %exit1.loopexit +loop_exiting_bb2: + br i1 false, label %loop_latch, label %bb +bb: + br label %exit1 +loop_latch: + %iv_next = add nuw nsw i64 %iv, 1 + %cmp = icmp ne i64 %iv_next, 2 + br i1 %cmp, label %loop_header, label %exit2 +exit1.loopexit: + br label %exit1 +exit1: + ret void +exit2: + ret void +} +