summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2016-02-17 18:42:17 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2016-02-17 18:42:17 +0000
commit596f5595034bdb3f83bf2b34b1e87a14cc70565a (patch)
tree8692760af9786c690100228a2a4414e1ea757d86
parent47ef236fe9b1fb8ab353334f18a86770c414a645 (diff)
downloadllvm-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.h8
-rw-r--r--llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp11
-rw-r--r--llvm/test/Transforms/LoopStrengthReduce/funclet.ll29
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