[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