forked from OSchip/llvm-project
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. llvm-svn: 177986
This commit is contained in:
parent
b45836a231
commit
9093e15066
|
@ -338,6 +338,10 @@ namespace llvm {
|
||||||
/// getMax - Get the max backedge taken count for the loop.
|
/// getMax - Get the max backedge taken count for the loop.
|
||||||
const SCEV *getMax(ScalarEvolution *SE) const;
|
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.
|
/// clear - Invalidate this result and free associated memory.
|
||||||
void clear();
|
void clear();
|
||||||
};
|
};
|
||||||
|
|
|
@ -4230,6 +4230,25 @@ ScalarEvolution::BackedgeTakenInfo::getMax(ScalarEvolution *SE) const {
|
||||||
return Max ? Max : SE->getCouldNotCompute();
|
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
|
/// Allocate memory for BackedgeTakenInfo and copy the not-taken count of each
|
||||||
/// computable exit into a persistent ExitNotTakenInfo array.
|
/// computable exit into a persistent ExitNotTakenInfo array.
|
||||||
ScalarEvolution::BackedgeTakenInfo::BackedgeTakenInfo(
|
ScalarEvolution::BackedgeTakenInfo::BackedgeTakenInfo(
|
||||||
|
@ -6940,6 +6959,17 @@ void ScalarEvolution::forgetMemoizedResults(const SCEV *S) {
|
||||||
BlockDispositions.erase(S);
|
BlockDispositions.erase(S);
|
||||||
UnsignedRanges.erase(S);
|
UnsignedRanges.erase(S);
|
||||||
SignedRanges.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;
|
typedef DenseMap<const Loop *, std::string> VerifyMap;
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue