[PATCH] D12799: [ValueTracking] Teach isKnownNonZero a new trick

James Molloy via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 11 05:51:20 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 the shifter operand is a constant, and all of the bits shifted out are known to be zero, then if X is known non-zero at least one non-zero bit must remain.

Repository:
  rL LLVM

http://reviews.llvm.org/D12799

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

Index: unittests/Analysis/ValueTrackingTest.cpp
===================================================================
--- unittests/Analysis/ValueTrackingTest.cpp
+++ unittests/Analysis/ValueTrackingTest.cpp
@@ -21,7 +21,7 @@
 
 namespace {
 
-class MatchSelectPatternTest : public testing::Test {
+class AssemblyParsingTestHelper {
 protected:
   void parseAssembly(const char *Assembly) {
     SMDiagnostic Error;
@@ -50,19 +50,31 @@
       report_fatal_error("@test must have an instruction %A");
   }
 
+  std::unique_ptr<Module> M;
+  Instruction *A;
+};
+  
+class MatchSelectPatternTest : public testing::Test,
+                               public AssemblyParsingTestHelper {
+protected:
   void expectPattern(const SelectPatternResult &P) {
     Value *LHS, *RHS;
     Instruction::CastOps CastOp;
     SelectPatternResult R = matchSelectPattern(A, LHS, RHS, &CastOp);
     EXPECT_EQ(P.Flavor, R.Flavor);
     EXPECT_EQ(P.NaNBehavior, R.NaNBehavior);
     EXPECT_EQ(P.Ordered, R.Ordered);
   }
-
-  std::unique_ptr<Module> M;
-  Instruction *A, *B;
 };
 
+class KnownValueTest : public testing::Test,
+                       public AssemblyParsingTestHelper {
+protected:
+  void expectKnownNonZero() {
+    EXPECT_TRUE(isKnownNonZero(A, M->getDataLayout()));
+  }
+};
+  
 }
 
 TEST_F(MatchSelectPatternTest, SimpleFMin) {
@@ -187,3 +199,16 @@
   // The cast types here aren't the same, so we cannot match an UMIN.
   expectPattern({SPF_UNKNOWN, SPNB_NA, false});
 }
+
+TEST_F(KnownValueTest, NonZeroShiftRight) {
+  parseAssembly(
+    "define i8 @test(i8 %p, i8* %pq) {\n"
+    "  %q = load i8, i8* %pq, !range !0\n" // %q is known nonzero; no known bits
+    "  %1 = or i8 %p, 1\n"   // %1[0] = 1, %1 is odd
+    "  %2 = shl i8 %1, %q\n" // %2[0] = 0, rest unknown but cannot be zero
+    "  %A = lshr i8 %2, 1\n" // We should know that %A is nonzero.
+    "  ret i8 %A\n"
+    "}\n"
+    "!0 = !{ i8 1, i8 5 }\n");
+  expectKnownNonZero();
+}
Index: lib/Analysis/ValueTracking.cpp
===================================================================
--- lib/Analysis/ValueTracking.cpp
+++ lib/Analysis/ValueTracking.cpp
@@ -1824,6 +1824,19 @@
     ComputeSignBit(X, XKnownNonNegative, XKnownNegative, DL, Depth, Q);
     if (XKnownNegative)
       return true;
+
+    // If the shifter operand is a constant, and all of the bits shifted
+    // out are known to be zero, and X is known non-zero then at least one
+    // non-zero bit must remain.
+    if (ConstantInt *Shift = dyn_cast<ConstantInt>(Y))
+      if (Shift->getLimitedValue() < BitWidth) {
+        APInt KnownZero(BitWidth, 0);
+        APInt KnownOne(BitWidth, 0);
+        computeKnownBits(X, KnownZero, KnownOne, DL, Depth, Q);
+        APInt LoBits = APInt::getLowBitsSet(BitWidth, Shift->getLimitedValue());
+        if ((KnownZero & LoBits).eq(LoBits))
+          return KnownOne.getBoolValue() || isKnownNonZero(X, DL, Depth, Q);
+      }
   }
   // div exact can only produce a zero if the dividend is zero.
   else if (match(V, m_Exact(m_IDiv(m_Value(X), m_Value())))) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D12799.34543.patch
Type: text/x-patch
Size: 3056 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150911/65301805/attachment.bin>


More information about the llvm-commits mailing list