[PATCH] D12800: [ValueTracking] Teach isKnownNonZero about monotonically increasing PHIs

James Molloy via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 11 05:54:01 PDT 2015


jmolloy created this revision.
jmolloy added reviewers: majnemer, hfinkel.
jmolloy added a subscriber: llvm-commits.
jmolloy set the repository for this revision to rL LLVM.

If a PHI starts at a non-negative constant, monotonically increases (only adds of a constant are supported at the moment) and that add does not wrap, then the PHI is known never to be zero.

Repository:
  rL LLVM

http://reviews.llvm.org/D12800

Files:
  lib/Analysis/ValueTracking.cpp
  unittests/Analysis/ValueTrackingTest.cpp

Index: unittests/Analysis/ValueTrackingTest.cpp
===================================================================
--- unittests/Analysis/ValueTrackingTest.cpp
+++ unittests/Analysis/ValueTrackingTest.cpp
@@ -70,8 +70,8 @@
 class KnownValueTest : public testing::Test,
                        public AssemblyParsingTestHelper {
 protected:
-  void expectKnownNonZero() {
-    EXPECT_TRUE(isKnownNonZero(A, M->getDataLayout()));
+  bool knownNonZero() {
+    return isKnownNonZero(A, M->getDataLayout());
   }
 };
   
@@ -210,5 +210,35 @@
     "  ret i8 %A\n"
     "}\n"
     "!0 = !{ i8 1, i8 5 }\n");
-  expectKnownNonZero();
+  EXPECT_TRUE(knownNonZero());
+}
+
+TEST_F(KnownValueTest, MonotonicPHI) {
+  parseAssembly(
+    "define i8 @test(i8* %pq) {\n"
+    "entry:\n"
+    "  br label %loop\n"
+    "loop:\n"
+    "  %A = phi i8 [ 1, %entry ], [ %next, %loop ]\n"
+    "  %next = add nsw nuw i8 %A, 1"
+    "  br label %loop\n"
+    "exit:\n"
+    "  unreachable\n"
+    "}\n");
+  EXPECT_TRUE(knownNonZero());
+}
+
+TEST_F(KnownValueTest, MonotonicWrappingPHI) {
+  parseAssembly(
+    "define i8 @test(i8* %pq) {\n"
+    "entry:\n"
+    "  br label %loop\n"
+    "loop:\n"
+    "  %A = phi i8 [ 1, %entry ], [ %next, %loop ]\n"
+    "  %next = add i8 %A, 1"
+    "  br label %loop\n"
+    "exit:\n"
+    "  unreachable\n"
+    "}\n");
+  EXPECT_FALSE(knownNonZero());
 }
Index: lib/Analysis/ValueTracking.cpp
===================================================================
--- lib/Analysis/ValueTracking.cpp
+++ lib/Analysis/ValueTracking.cpp
@@ -1896,6 +1896,26 @@
         isKnownNonZero(SI->getFalseValue(), DL, Depth, Q))
       return true;
   }
+  // PHI
+  else if (PHINode *PN = dyn_cast<PHINode>(V)) {
+    // Try and detect a recurrence that monotonically increases from a
+    // starting value, as these are common as induction variables.
+    if (PN->getNumIncomingValues() == 2) {
+      Value *Op1 = PN->getIncomingValue(0);
+      Value *Op2 = PN->getIncomingValue(1);
+      if (isa<ConstantInt>(Op2) && !isa<ConstantInt>(Op1))
+        std::swap(Op1, Op2);
+      if (ConstantInt *COp1 = dyn_cast<ConstantInt>(Op1)) {
+        if (!COp1->isZero() && !COp1->isNegative()) {
+          ConstantInt *X;
+          if (match(Op2, m_NSWAdd(m_Specific(PN), m_ConstantInt(X))) &&
+              match(Op2, m_NUWAdd(m_Specific(PN), m_ConstantInt(X))) &&
+              !X->isNegative())
+            return true;
+        }
+      }
+    }
+  }
 
   if (!BitWidth) return false;
   APInt KnownZero(BitWidth, 0);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D12800.34544.patch
Type: text/x-patch
Size: 2535 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150911/5b281f3e/attachment.bin>


More information about the llvm-commits mailing list