diff options
author | David Majnemer <david.majnemer@gmail.com> | 2016-02-17 18:42:17 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2016-02-17 18:42:17 +0000 |
commit | 596f5595034bdb3f83bf2b34b1e87a14cc70565a (patch) | |
tree | 8692760af9786c690100228a2a4414e1ea757d86 | |
parent | 47ef236fe9b1fb8ab353334f18a86770c414a645 (diff) | |
download | llvm-596f5595034bdb3f83bf2b34b1e87a14cc70565a.tar.gz |
Merging r259702:
------------------------------------------------------------------------
r259702 | majnemer | 2016-02-03 13:30:34 -0800 (Wed, 03 Feb 2016) | 7 lines
[LoopStrengthReduce] Don't rewrite PHIs with incoming values from CatchSwitches
Bail out if we have a PHI on an EHPad that gets a value from a
CatchSwitchInst. Because the CatchSwitchInst cannot be split, there is
no good place to stick any instructions.
This fixes PR26373.
------------------------------------------------------------------------
llvm-svn: 261126
-rw-r--r-- | llvm/include/llvm/IR/Instructions.h | 8 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp | 11 | ||||
-rw-r--r-- | llvm/test/Transforms/LoopStrengthReduce/funclet.ll | 29 |
3 files changed, 48 insertions, 0 deletions
diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h index aba48ca6fa9e..28e1fd90fdf6 100644 --- a/llvm/include/llvm/IR/Instructions.h +++ b/llvm/include/llvm/IR/Instructions.h @@ -2512,6 +2512,14 @@ public: return block_begin() + getNumOperands(); } + iterator_range<block_iterator> blocks() { + return make_range(block_begin(), block_end()); + } + + iterator_range<const_block_iterator> blocks() const { + return make_range(block_begin(), block_end()); + } + op_range incoming_values() { return operands(); } const_op_range incoming_values() const { return operands(); } diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp index 2101225ed9f7..acfdec43d21a 100644 --- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -4799,6 +4799,17 @@ LSRInstance::LSRInstance(Loop *L, IVUsers &IU, ScalarEvolution &SE, DEBUG(dbgs() << "LSR skipping loop, too many IV Users in " << U << "\n"); return; } + // Bail out if we have a PHI on an EHPad that gets a value from a + // CatchSwitchInst. Because the CatchSwitchInst cannot be split, there is + // no good place to stick any instructions. + if (auto *PN = dyn_cast<PHINode>(U.getUser())) { + auto *FirstNonPHI = PN->getParent()->getFirstNonPHI(); + if (isa<FuncletPadInst>(FirstNonPHI) || + isa<CatchSwitchInst>(FirstNonPHI)) + for (BasicBlock *PredBB : PN->blocks()) + if (isa<CatchSwitchInst>(PredBB->getFirstNonPHI())) + return; + } } #ifndef NDEBUG diff --git a/llvm/test/Transforms/LoopStrengthReduce/funclet.ll b/llvm/test/Transforms/LoopStrengthReduce/funclet.ll index 5d20646141c4..1bee3706cafa 100644 --- a/llvm/test/Transforms/LoopStrengthReduce/funclet.ll +++ b/llvm/test/Transforms/LoopStrengthReduce/funclet.ll @@ -214,3 +214,32 @@ try.cont.7: ; preds = %try.cont ; CHECK: catch.dispatch.2: ; CHECK: %e.0 = phi i32* [ %c, %try.cont ], [ %b, %catch.dispatch ] + +define i32 @test2() personality i32 (...)* @_except_handler3 { +entry: + br label %for.body + +for.body: ; preds = %for.inc, %entry + %phi = phi i32 [ %inc, %for.inc ], [ 0, %entry ] + invoke void @reserve() + to label %for.inc unwind label %catch.dispatch + +catch.dispatch: ; preds = %for.body + %tmp18 = catchswitch within none [label %catch.handler] unwind to caller + +catch.handler: ; preds = %catch.dispatch + %phi.lcssa = phi i32 [ %phi, %catch.dispatch ] + %tmp19 = catchpad within %tmp18 [i8* null] + catchret from %tmp19 to label %done + +done: + ret i32 %phi.lcssa + +for.inc: ; preds = %for.body + %inc = add i32 %phi, 1 + br label %for.body +} + +; CHECK-LABEL: define i32 @test2( +; CHECK: %phi.lcssa = phi i32 [ %phi, %catch.dispatch ] +; CHECK-NEXT: catchpad within |