Index: lib/Transforms/Utils/BasicBlockUtils.cpp =================================================================== --- lib/Transforms/Utils/BasicBlockUtils.cpp +++ lib/Transforms/Utils/BasicBlockUtils.cpp @@ -331,6 +331,13 @@ bool IsLoopEntry = !!L; bool SplitMakesNewLoopHeader = false; for (BasicBlock *Pred : Preds) { + // Preds that are not reachable from entry should not be used to identify if + // OldBB is a loop entry or if SplitMakesNewLoopHeader. Blocks that do not + // have any predecessors are not within any loops, so we incorrectly mark + // SplitMakesNewLoopHeader as true and make the NewBB the header of some + // loop. This breaks LI. + if (!DT->isReachableFromEntry(Pred)) + continue; // If we need to preserve LCSSA, determine if any of the preds is a loop // exit. if (PreserveLCSSA) Index: test/Transforms/LoopSimplify/unreachable-loop-pred.ll =================================================================== --- test/Transforms/LoopSimplify/unreachable-loop-pred.ll +++ test/Transforms/LoopSimplify/unreachable-loop-pred.ll @@ -18,3 +18,74 @@ foo: br label %while.body115 } + +; When loopsimplify generates dedicated exit blocks for blocks that are landing +; pads, we should not incorrectly mark that exit block as the header for the outer +; loop. This happens when it gets confused with the unreachable pred to the inner +; loop exit block +define align 8 void @baz() personality i32* ()* @wobble { +bb: + br label %outerH + +outerH: + %tmp30 = invoke align 8 i8 * undef() + to label %outerLExiting1 unwind label %unwindblock + +unwindblock: + %tmp34 = landingpad { i8*, i32 } + cleanup + ret void + +outerLExiting1: + br i1 undef, label %outerLExiting2, label %exit + +exit: + ret void + +outerLExiting2: + invoke void @foo() + to label %innerPreheader unwind label %innerLExit + +innerPreheader: ; preds = %outerLExiting2 + br label %innerH + +innerH: ; preds = %innerLatch, %innerPreheader + %tmp50 = invoke i8 * undef() + to label %innerExiting unwind label %innerLExit + +innerExiting: ; preds = %bb57 + invoke align 8 void @foo() + to label %innerLatch unwind label %innerLExit + +innerLatch: ; preds = %innerExiting + br label %innerH + +; This is a predecessor for inner loop exit block which is a landing pad. +unreachableB: ; No predecessors! + %tmp62 = invoke i8 * undef() + to label %unwindblock2 unwind label %innerLExit + +unwindblock2: ; preds = %unreachableB + ret void + +innerLExit: + %tmp65 = landingpad { i8*, i32 } + cleanup + invoke void @foo() + to label %outerLatch unwind label %bb66 + +bb66: ; preds = %innerLExit + %tmp67 = landingpad { i8*, i32 } + cleanup + ret void + + +outerLatch: ; preds = %bb70 + br label %outerH +} + +; Function Attrs: nounwind +declare i32* @wobble() + +; Function Attrs: uwtable +declare void @foo()