[NaryReassociate] SeenExprs records WeakVH
authorJingyue Wu <jingyue@google.com>
Thu, 1 Oct 2015 03:51:44 +0000 (03:51 +0000)
committerJingyue Wu <jingyue@google.com>
Thu, 1 Oct 2015 03:51:44 +0000 (03:51 +0000)
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

lib/Transforms/Scalar/NaryReassociate.cpp
test/Transforms/NaryReassociate/pr24301.ll [new file with mode: 0644]

index c6cb12f77fa0a3476aee35a03f53c7ed4335e167..972bd335c8527c525dd80ea5832046e63c96c05c 100644 (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;
diff --git a/test/Transforms/NaryReassociate/pr24301.ll b/test/Transforms/NaryReassociate/pr24301.ll
new file mode 100644 (file)
index 0000000..8987078
--- /dev/null
@@ -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
+}