[NaryReassociate] SeenExprs records WeakVH

Summary:
The instructions SeenExprs records may be deleted during rewriting.
FindClosestMatchingDominator should ignore these deleted instructions.

Fixes PR24301.

Reviewers: grosser

Subscribers: grosser, llvm-commits

Differential Revision: http://reviews.llvm.org/D13315

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@248983 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jingyue Wu 2015-10-01 03:51:44 +00:00
parent 2eee2e2c5e
commit fd5a6e2618
2 changed files with 26 additions and 6 deletions

View File

@ -188,7 +188,7 @@ private:
// foo(a + b);
// if (p2)
// bar(a + b);
DenseMap<const SCEV *, SmallVector<Instruction *, 2>> SeenExprs;
DenseMap<const SCEV *, SmallVector<WeakVH, 2>> SeenExprs;
};
} // anonymous namespace
@ -252,13 +252,15 @@ bool NaryReassociate::doOneIteration(Function &F) {
Changed = true;
SE->forgetValue(I);
I->replaceAllUsesWith(NewI);
// If SeenExprs constains I's WeakVH, that entry will be replaced with
// nullptr.
RecursivelyDeleteTriviallyDeadInstructions(I, TLI);
I = NewI;
}
// Add the rewritten instruction to SeenExprs; the original instruction
// is deleted.
const SCEV *NewSCEV = SE->getSCEV(I);
SeenExprs[NewSCEV].push_back(I);
SeenExprs[NewSCEV].push_back(WeakVH(I));
// Ideally, NewSCEV should equal OldSCEV because tryReassociate(I)
// is equivalent to I. However, ScalarEvolution::getSCEV may
// weaken nsw causing NewSCEV not to equal OldSCEV. For example, suppose
@ -278,7 +280,7 @@ bool NaryReassociate::doOneIteration(Function &F) {
//
// This improvement is exercised in @reassociate_gep_nsw in nary-gep.ll.
if (NewSCEV != OldSCEV)
SeenExprs[OldSCEV].push_back(I);
SeenExprs[OldSCEV].push_back(WeakVH(I));
}
}
}
@ -562,9 +564,13 @@ NaryReassociate::findClosestMatchingDominator(const SCEV *CandidateExpr,
// future instruction either. Therefore, we pop it out of the stack. This
// optimization makes the algorithm O(n).
while (!Candidates.empty()) {
Instruction *Candidate = Candidates.back();
if (DT->dominates(Candidate, Dominatee))
return Candidate;
// Candidates stores WeakVHs, so a candidate can be nullptr if it's removed
// during rewriting.
if (Value *Candidate = Candidates.back()) {
Instruction *CandidateInstruction = cast<Instruction>(Candidate);
if (DT->dominates(CandidateInstruction, Dominatee))
return CandidateInstruction;
}
Candidates.pop_back();
}
return nullptr;

View File

@ -0,0 +1,14 @@
; RUN: opt < %s -nary-reassociate -S | FileCheck %s
define i32 @foo(i32 %tmp4) {
; CHECK-LABEL: @foo(
entry:
%tmp5 = add i32 %tmp4, 8
%tmp13 = add i32 %tmp4, -128 ; deleted
%tmp14 = add i32 %tmp13, 8 ; => %tmp5 + -128
%tmp21 = add i32 119, %tmp4
; do not rewrite %tmp23 against %tmp13 because %tmp13 is already deleted
%tmp23 = add i32 %tmp21, -128
; CHECK: %tmp23 = add i32 %tmp21, -128
ret i32 %tmp23
}