[llvm-commits] [llvm] r157092 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolution.h lib/Analysis/ScalarEvolution.cpp test/Analysis/ScalarEvolution/2012-05-18-LoopPredRecurse.ll

Andrew Trick atrick at apple.com
Fri May 18 17:48:25 PDT 2012


Author: atrick
Date: Fri May 18 19:48:25 2012
New Revision: 157092

URL: http://llvm.org/viewvc/llvm-project?rev=157092&view=rev
Log:
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.

Added:
    llvm/trunk/test/Analysis/ScalarEvolution/2012-05-18-LoopPredRecurse.ll
Modified:
    llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
    llvm/trunk/lib/Analysis/ScalarEvolution.cpp

Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=157092&r1=157091&r2=157092&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original)
+++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Fri May 18 19:48:25 2012
@@ -30,7 +30,7 @@
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/ConstantRange.h"
 #include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
 #include <map>
 
 namespace llvm {
@@ -250,6 +250,9 @@
     ///
     ValueExprMapType ValueExprMap;
 
+    /// Mark predicate values currently being processed by isImpliedCond.
+    DenseSet<Value*> PendingLoopPredicates;
+
     /// ExitLimit - Information about the number of loop iterations for
     /// which a loop exit's branch condition evaluates to the not-taken path.
     /// This is a temporary pair of exact and max expressions that are

Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=157092&r1=157091&r2=157092&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Fri May 18 19:48:25 2012
@@ -6039,12 +6039,34 @@
   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 @@
     I->second.clear();
   }
 
+  assert(PendingLoopPredicates.empty() && "isImpliedCond garbage");
+
   BackedgeTakenCounts.clear();
   ConstantEvolutionLoopExitValue.clear();
   ValuesAtScopes.clear();

Added: llvm/trunk/test/Analysis/ScalarEvolution/2012-05-18-LoopPredRecurse.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2012-05-18-LoopPredRecurse.ll?rev=157092&view=auto
==============================================================================
--- llvm/trunk/test/Analysis/ScalarEvolution/2012-05-18-LoopPredRecurse.ll (added)
+++ llvm/trunk/test/Analysis/ScalarEvolution/2012-05-18-LoopPredRecurse.ll Fri May 18 19:48:25 2012
@@ -0,0 +1,30 @@
+; RUN: opt < %s -iv-users -S -disable-output
+;
+; PR12868: Infinite recursion:
+; getUDivExpr()->getZeroExtendExpr()->isLoopBackedgeGuardedBy()
+;
+; We actually want SCEV simplification to fail gracefully in this
+; case, so there's no output to check, just the absense of stack overflow.
+
+ at c = common global i8 0, align 1
+
+define i32 @func() {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.body, %entry
+  %storemerge = phi i8 [ -1, %entry ], [ %inc, %for.body ]
+  %ui.0 = phi i32 [ undef, %entry ], [ %div, %for.body ]
+  %tobool = icmp eq i8 %storemerge, 0
+  br i1 %tobool, label %for.end, label %for.body
+
+for.body:                                         ; preds = %for.cond
+  %conv = sext i8 %storemerge to i32
+  %div = lshr i32 %conv, 1
+  %tobool2 = icmp eq i32 %div, 0
+  %inc = add i8 %storemerge, 1
+  br i1 %tobool2, label %for.cond, label %for.end
+
+for.end:                                          ; preds = %for.body, %for.cond
+  ret i32 0
+}





More information about the llvm-commits mailing list