From: Jingyue Wu Date: Thu, 1 Oct 2015 03:51:44 +0000 (+0000) Subject: [NaryReassociate] SeenExprs records WeakVH X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=fd5a6e2618cea2de1b48b3b559d1bd257ec8f544;p=oota-llvm.git [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 --- diff --git a/lib/Transforms/Scalar/NaryReassociate.cpp b/lib/Transforms/Scalar/NaryReassociate.cpp index c6cb12f77fa..972bd335c85 100644 --- a/lib/Transforms/Scalar/NaryReassociate.cpp +++ b/lib/Transforms/Scalar/NaryReassociate.cpp @@ -188,7 +188,7 @@ private: // foo(a + b); // if (p2) // bar(a + b); - DenseMap> SeenExprs; + DenseMap> 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(Candidate); + if (DT->dominates(CandidateInstruction, Dominatee)) + return CandidateInstruction; + } Candidates.pop_back(); } return nullptr; diff --git a/test/Transforms/NaryReassociate/pr24301.ll b/test/Transforms/NaryReassociate/pr24301.ll new file mode 100644 index 00000000000..898707831f9 --- /dev/null +++ b/test/Transforms/NaryReassociate/pr24301.ll @@ -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 +}