mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-02 08:26:29 +00:00
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
5bf5043e5b
commit
57ddfcf201
@ -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();
|
||||
};
|
||||
|
@ -4230,6 +4230,25 @@ ScalarEvolution::BackedgeTakenInfo::getMax(ScalarEvolution *SE) const {
|
||||
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::forgetMemoizedResults(const SCEV *S) {
|
||||
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;
|
||||
|
34
test/Analysis/ScalarEvolution/scev-invalid.ll
Normal file
34
test/Analysis/ScalarEvolution/scev-invalid.ll
Normal file
@ -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
Block a user