OSDN Git Service

NewGVN: Fix PR 33116, the memoryphi version of bug 32838.
authorDaniel Berlin <dberlin@dberlin.org>
Sun, 21 May 2017 23:41:58 +0000 (23:41 +0000)
committerDaniel Berlin <dberlin@dberlin.org>
Sun, 21 May 2017 23:41:58 +0000 (23:41 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303521 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 3e45f8d..5cfbf6b 100644 (file)
@@ -61,7 +61,6 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/SparseBitVector.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/TinyPtrVector.h"
 #include "llvm/Analysis/AliasAnalysis.h"
@@ -1224,7 +1223,6 @@ const Expression *NewGVN::performSymbolicStoreEvaluation(Instruction *I) const {
   // If we bypassed the use-def chains, make sure we add a use.
   if (StoreRHS != StoreAccess->getDefiningAccess())
     addMemoryUsers(StoreRHS, StoreAccess);
-
   StoreRHS = lookupMemoryLeader(StoreRHS);
   // If we are defined by ourselves, use the live on entry def.
   if (StoreRHS == StoreAccess)
@@ -1596,7 +1594,7 @@ const Expression *NewGVN::performSymbolicPHIEvaluation(Instruction *I) const {
   // See if all arguments are the same.
   // We track if any were undef because they need special handling.
   bool HasUndef = false;
-  bool CycleFree = isCycleFree(cast<PHINode>(I));
+  bool CycleFree = isCycleFree(I);
   auto Filtered = make_filter_range(E->operands(), [&](Value *Arg) {
     if (Arg == nullptr)
       return false;
@@ -2709,11 +2707,12 @@ void NewGVN::updateProcessedCount(const Value *V) {
 // Evaluate MemoryPhi nodes symbolically, just like PHI nodes
 void NewGVN::valueNumberMemoryPhi(MemoryPhi *MP) {
   // If all the arguments are the same, the MemoryPhi has the same value as the
-  // argument.
-  // Filter out unreachable blocks and self phis from our operands.
+  // argument.  Filter out unreachable blocks and self phis from our operands.
+  // TODO: We could do cycle-checking on the memory phis to allow valueizing for
+  // self-phi checking.
   const BasicBlock *PHIBlock = MP->getBlock();
   auto Filtered = make_filter_range(MP->operands(), [&](const Use &U) {
-    return lookupMemoryLeader(cast<MemoryAccess>(U)) != MP &&
+    return cast<MemoryAccess>(U) != MP &&
            !isMemoryAccessTOP(cast<MemoryAccess>(U)) &&
            ReachableEdges.count({MP->getIncomingBlock(U), PHIBlock});
   });
diff --git a/test/Transforms/NewGVN/pr33116.ll b/test/Transforms/NewGVN/pr33116.ll
new file mode 100644 (file)
index 0000000..9bf6bb1
--- /dev/null
@@ -0,0 +1,39 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -newgvn %s | FileCheck %s
+
+@a = external global i32
+
+define void @b() {
+; CHECK-LABEL: @b(
+; CHECK-NEXT:    br i1 false, label [[C:%.*]], label [[WHILE_D:%.*]]
+; CHECK:       while.d:
+; CHECK-NEXT:    br label [[F:%.*]]
+; CHECK:       f:
+; CHECK-NEXT:    br i1 undef, label [[IF_E:%.*]], label [[C]]
+; CHECK:       c:
+; CHECK-NEXT:    br i1 undef, label [[IF_G:%.*]], label [[IF_E]]
+; CHECK:       if.g:
+; CHECK-NEXT:    store i32 undef, i32* @a
+; CHECK-NEXT:    br label [[WHILE_D]]
+; CHECK:       if.e:
+; CHECK-NEXT:    br label [[F]]
+;
+  br i1 false, label %c, label %while.d
+
+while.d:                                          ; preds = %if.g, %0
+  br label %f
+
+f:                                                ; preds = %if.e, %while.d
+  br i1 undef, label %if.e, label %c
+
+c:                                                ; preds = %f, %0
+  br i1 undef, label %if.g, label %if.e
+
+if.g:                                             ; preds = %c
+  store i32 undef, i32* @a
+  br label %while.d
+
+if.e:                                             ; preds = %c, %f
+  br label %f
+}
+