diff --git a/lib/Transforms/Utils/BasicBlockUtils.cpp b/lib/Transforms/Utils/BasicBlockUtils.cpp index 4931ab3f7fa..35907fdcc1a 100644 --- a/lib/Transforms/Utils/BasicBlockUtils.cpp +++ b/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -425,14 +425,26 @@ BasicBlock *llvm::SplitBlockPredecessors(BasicBlock *BB, if (L) { if (IsLoopEntry) { - if (Loop *PredLoop = LI->getLoopFor(Preds[0])) { - // Add the new block to the nearest enclosing loop (and not an - // adjacent loop). - while (PredLoop && !PredLoop->contains(BB)) - PredLoop = PredLoop->getParentLoop(); - if (PredLoop) - PredLoop->addBasicBlockToLoop(NewBB, LI->getBase()); - } + // Add the new block to the nearest enclosing loop (and not an + // adjacent loop). To find this, examine each of the predecessors and + // determine which loops enclose them, and select the most-nested loop + // which contains the loop containing the block being split. + Loop *InnermostPredLoop = 0; + for (unsigned i = 0; i != NumPreds; ++i) + if (Loop *PredLoop = LI->getLoopFor(Preds[i])) { + // Seek a loop which actually contains the block being split (to + // avoid adjacent loops). + while (PredLoop && !PredLoop->contains(BB)) + PredLoop = PredLoop->getParentLoop(); + // Select the most-nested of these loops which contains the block. + if (PredLoop && + PredLoop->contains(BB) && + (!InnermostPredLoop || + InnermostPredLoop->getLoopDepth() < PredLoop->getLoopDepth())) + InnermostPredLoop = PredLoop; + } + if (InnermostPredLoop) + InnermostPredLoop->addBasicBlockToLoop(NewBB, LI->getBase()); } else { L->addBasicBlockToLoop(NewBB, LI->getBase()); if (SplitMakesNewLoopHeader) diff --git a/test/Transforms/LoopSimplify/unreachable-loop-pred.ll b/test/Transforms/LoopSimplify/unreachable-loop-pred.ll new file mode 100644 index 00000000000..faaaf97d72f --- /dev/null +++ b/test/Transforms/LoopSimplify/unreachable-loop-pred.ll @@ -0,0 +1,20 @@ +; RUN: opt -S -loopsimplify -disable-output -verify-loop-info -verify-dom-info < %s +; PR5235 + +; When loopsimplify inserts a preheader for this loop, it should add the new +; block to the enclosing loop and not get confused by the unreachable +; bogus loop entry. + +define void @is_extract_cab() nounwind { +entry: + br label %header + +header: ; preds = %if.end206, %cond.end66, %if.end23 + br label %while.body115 + +while.body115: ; preds = %9, %if.end192, %if.end101 + br i1 undef, label %header, label %while.body115 + +foo: + br label %while.body115 +}