[llvm] r177986 - Fix SCEV forgetMemoizedResults should search and destroy backedge exprs.

Andrew Trick atrick at apple.com
Mon Mar 25 20:14:53 PDT 2013


Author: atrick
Date: Mon Mar 25 22:14:53 2013
New Revision: 177986

URL: http://llvm.org/viewvc/llvm-project?rev=177986&view=rev
Log:
Fix SCEV forgetMemoizedResults should search and destroy backedge exprs.

Fixes PR15570: SEGV: SCEV back-edge info invalid after dead code removal.

Indvars creates a SCEV expression for the loop's back edge taken
count, then determines that the comparison is always true and
removes it.

When loop-unroll asks for the expression, it contains a NULL
SCEVUnknkown (as a CallbackVH).

forgetMemoizedResults should invalidate the loop back edges expression.

Added:
    llvm/trunk/test/Analysis/ScalarEvolution/scev-invalid.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=177986&r1=177985&r2=177986&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original)
+++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Mon Mar 25 22:14:53 2013
@@ -338,6 +338,10 @@ namespace llvm {
       /// getMax - Get the max backedge taken count for the loop.
       const SCEV *getMax(ScalarEvolution *SE) const;
 
+      /// Return true if any backedge taken count expressions refer to the given
+      /// subexpression.
+      bool hasOperand(const SCEV *S, ScalarEvolution *SE) const;
+
       /// clear - Invalidate this result and free associated memory.
       void clear();
     };

Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=177986&r1=177985&r2=177986&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Mon Mar 25 22:14:53 2013
@@ -4230,6 +4230,25 @@ ScalarEvolution::BackedgeTakenInfo::getM
   return Max ? Max : SE->getCouldNotCompute();
 }
 
+bool ScalarEvolution::BackedgeTakenInfo::hasOperand(const SCEV *S,
+                                                    ScalarEvolution *SE) const {
+  if (Max && Max != SE->getCouldNotCompute() && SE->hasOperand(Max, S))
+    return true;
+
+  if (!ExitNotTaken.ExitingBlock)
+    return false;
+
+  for (const ExitNotTakenInfo *ENT = &ExitNotTaken;
+       ENT != 0; ENT = ENT->getNextExit()) {
+
+    if (ENT->ExactNotTaken != SE->getCouldNotCompute()
+        && SE->hasOperand(ENT->ExactNotTaken, S)) {
+      return true;
+    }
+  }
+  return false;
+}
+
 /// Allocate memory for BackedgeTakenInfo and copy the not-taken count of each
 /// computable exit into a persistent ExitNotTakenInfo array.
 ScalarEvolution::BackedgeTakenInfo::BackedgeTakenInfo(
@@ -6940,6 +6959,17 @@ void ScalarEvolution::forgetMemoizedResu
   BlockDispositions.erase(S);
   UnsignedRanges.erase(S);
   SignedRanges.erase(S);
+
+  for (DenseMap<const Loop*, BackedgeTakenInfo>::iterator I =
+         BackedgeTakenCounts.begin(), E = BackedgeTakenCounts.end(); I != E; ) {
+    BackedgeTakenInfo &BEInfo = I->second;
+    if (BEInfo.hasOperand(S, this)) {
+      BEInfo.clear();
+      BackedgeTakenCounts.erase(I++);
+    }
+    else
+      ++I;
+  }
 }
 
 typedef DenseMap<const Loop *, std::string> VerifyMap;

Added: llvm/trunk/test/Analysis/ScalarEvolution/scev-invalid.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/scev-invalid.ll?rev=177986&view=auto
==============================================================================
--- llvm/trunk/test/Analysis/ScalarEvolution/scev-invalid.ll (added)
+++ llvm/trunk/test/Analysis/ScalarEvolution/scev-invalid.ll Mon Mar 25 22:14:53 2013
@@ -0,0 +1,34 @@
+; RUN: opt < %s -S -indvars -loop-unroll | FileCheck %s
+;
+; PR15570: SEGV: SCEV back-edge info invalid after dead code removal.
+;
+; Indvars creates a SCEV expression for the loop's back edge taken
+; count, then determines that the comparison is always true and
+; removes it.
+;
+; When loop-unroll asks for the expression, it contains a NULL
+; SCEVUnknkown (as a CallbackVH).
+;
+; forgetMemoizedResults should invalidate the backedge taken count expression.
+
+; CHECK: @test
+; CHECK-NOT: phi
+; CHECK-NOT: icmp
+; CHECK: ret void
+define void @test() {
+entry:
+  %xor1 = xor i32 0, 1
+  br label %b17
+
+b17:
+  br i1 undef, label %b22, label %b18
+
+b18:
+  %phi1 = phi i32 [ %add1, %b18 ], [ %xor1, %b17 ]
+  %add1 = add nsw i32 %phi1, -1
+  %cmp1 = icmp sgt i32 %add1, 0
+  br i1 %cmp1, label %b18, label %b22
+
+b22:
+  ret void
+}





More information about the llvm-commits mailing list