aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
authorAndrew Trick <atrick@apple.com>2012-05-19 00:48:25 +0000
committerAndrew Trick <atrick@apple.com>2012-05-19 00:48:25 +0000
commit8aa22019ca5ef29a15058be905d782e7225aa206 (patch)
tree8b4d0c98b890e76017e78904ec69c94f16457f96 /lib/Analysis/ScalarEvolution.cpp
parentce5d8b0d03b9c37727d08de4fa1bcc7be7ea8bb1 (diff)
downloadexternal_llvm-8aa22019ca5ef29a15058be905d782e7225aa206.zip
external_llvm-8aa22019ca5ef29a15058be905d782e7225aa206.tar.gz
external_llvm-8aa22019ca5ef29a15058be905d782e7225aa206.tar.bz2
SCEV: Add MarkPendingLoopPredicates to avoid recursive isImpliedCond.
getUDivExpr attempts to simplify by checking for overflow. isLoopEntryGuardedByCond then evaluates the loop predicate which may lead to the same getUDivExpr causing endless recursion. Fixes PR12868: clang 3.2 segmentation fault. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157092 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--lib/Analysis/ScalarEvolution.cpp24
1 files changed, 24 insertions, 0 deletions
diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp
index d1ad8e0..4e3dc60 100644
--- a/lib/Analysis/ScalarEvolution.cpp
+++ b/lib/Analysis/ScalarEvolution.cpp
@@ -6039,12 +6039,34 @@ ScalarEvolution::isLoopEntryGuardedByCond(const Loop *L,
return false;
}
+/// RAII wrapper to prevent recursive application of isImpliedCond.
+/// ScalarEvolution's PendingLoopPredicates set must be empty unless we are
+/// currently evaluating isImpliedCond.
+struct MarkPendingLoopPredicate {
+ Value *Cond;
+ DenseSet<Value*> &LoopPreds;
+ bool Pending;
+
+ MarkPendingLoopPredicate(Value *C, DenseSet<Value*> &LP)
+ : Cond(C), LoopPreds(LP) {
+ Pending = !LoopPreds.insert(Cond).second;
+ }
+ ~MarkPendingLoopPredicate() {
+ if (!Pending)
+ LoopPreds.erase(Cond);
+ }
+};
+
/// isImpliedCond - Test whether the condition described by Pred, LHS,
/// and RHS is true whenever the given Cond value evaluates to true.
bool ScalarEvolution::isImpliedCond(ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS,
Value *FoundCondValue,
bool Inverse) {
+ MarkPendingLoopPredicate Mark(FoundCondValue, PendingLoopPredicates);
+ if (Mark.Pending)
+ return false;
+
// Recursively handle And and Or conditions.
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(FoundCondValue)) {
if (BO->getOpcode() == Instruction::And) {
@@ -6571,6 +6593,8 @@ void ScalarEvolution::releaseMemory() {
I->second.clear();
}
+ assert(PendingLoopPredicates.empty() && "isImpliedCond garbage");
+
BackedgeTakenCounts.clear();
ConstantEvolutionLoopExitValue.clear();
ValuesAtScopes.clear();