diff options
Diffstat (limited to 'lib/Transforms/Utils/LoopSimplify.cpp')
-rw-r--r-- | lib/Transforms/Utils/LoopSimplify.cpp | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/lib/Transforms/Utils/LoopSimplify.cpp b/lib/Transforms/Utils/LoopSimplify.cpp index 6a9976930c..b019684021 100644 --- a/lib/Transforms/Utils/LoopSimplify.cpp +++ b/lib/Transforms/Utils/LoopSimplify.cpp @@ -398,6 +398,9 @@ BasicBlock *LoopSimplify::InsertPreheaderForLoop(Loop *L) { /// blocks. This method is used to split exit blocks that have predecessors /// outside of the loop. BasicBlock *LoopSimplify::RewriteLoopExitBlock(Loop *L, BasicBlock *Exit) { + // Don't split a landing pad block. + if (Exit->isLandingPad()) return 0; + SmallVector<BasicBlock*, 8> LoopBlocks; for (pred_iterator I = pred_begin(Exit), E = pred_end(Exit); I != E; ++I) { BasicBlock *P = *I; @@ -746,18 +749,29 @@ void LoopSimplify::verifyAnalysis() const { (void)HasIndBrPred; } - // Indirectbr can interfere with exit block canonicalization. + // Indirectbr and LandingPad can interfere with exit block canonicalization. if (!L->hasDedicatedExits()) { bool HasIndBrExiting = false; + bool HasLPadExiting = false; SmallVector<BasicBlock*, 8> ExitingBlocks; L->getExitingBlocks(ExitingBlocks); - for (unsigned i = 0, e = ExitingBlocks.size(); i != e; ++i) + for (unsigned i = 0, e = ExitingBlocks.size(); i != e; ++i) { if (isa<IndirectBrInst>((ExitingBlocks[i])->getTerminator())) { HasIndBrExiting = true; break; } - assert(HasIndBrExiting && + if (const InvokeInst *II = + dyn_cast<InvokeInst>(ExitingBlocks[i]->getTerminator())) { + if (L->contains(II->getNormalDest()) && + !L->contains(II->getUnwindDest())) { + HasLPadExiting = true; + break; + } + } + } + + assert((HasIndBrExiting || HasLPadExiting) && "LoopSimplify has no excuse for missing exit block info!"); - (void)HasIndBrExiting; + (void)HasIndBrExiting; (void)HasLPadExiting; } } |