aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/Utils/LoopSimplify.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms/Utils/LoopSimplify.cpp')
-rw-r--r--lib/Transforms/Utils/LoopSimplify.cpp22
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;
}
}