[llvm] 938d05b - [ValueTracking] Handle non-zero add/mul recurrences more precisely

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 26 10:30:18 PDT 2021


Author: Nikita Popov
Date: 2021-03-26T18:30:07+01:00
New Revision: 938d05b814c7fe470201d595afefc02e3371244e

URL: https://github.com/llvm/llvm-project/commit/938d05b814c7fe470201d595afefc02e3371244e
DIFF: https://github.com/llvm/llvm-project/commit/938d05b814c7fe470201d595afefc02e3371244e.diff

LOG: [ValueTracking] Handle non-zero add/mul recurrences more precisely

This is mainly for clarity: It doesn't make sense to do any
negative/positive checks when dealing with a nuw add/mul. These
only make sense to nsw add/mul.

Added: 
    

Modified: 
    llvm/lib/Analysis/ValueTracking.cpp
    llvm/test/Analysis/ValueTracking/monotonic-phi.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 4b9afdad8ff75..8e7858db38fd1 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -2213,6 +2213,31 @@ static bool rangeMetadataExcludesValue(const MDNode* Ranges, const APInt& Value)
   return true;
 }
 
+static bool isNonZeroRecurrence(const PHINode *PN) {
+  // Try and detect a recurrence that monotonically increases from a
+  // starting value, as these are common as induction variables.
+  BinaryOperator *BO = nullptr;
+  Value *Start = nullptr, *Step = nullptr;
+  const APInt *StartC, *StepC;
+  if (!matchSimpleRecurrence(PN, BO, Start, Step) ||
+      !match(Start, m_APInt(StartC)) || !match(Step, m_APInt(StepC)))
+    return false;
+
+  switch (BO->getOpcode()) {
+  case Instruction::Add:
+    return (BO->hasNoUnsignedWrap() && !StartC->isNullValue() &&
+            !StepC->isNullValue()) ||
+           (BO->hasNoSignedWrap() && StartC->isStrictlyPositive() &&
+            StepC->isNonNegative());
+  case Instruction::Mul:
+    return !StartC->isNullValue() &&
+           ((BO->hasNoUnsignedWrap() && !StepC->isNullValue()) ||
+            (BO->hasNoSignedWrap() && StepC->isStrictlyPositive()));
+  default:
+    return false;
+  }
+}
+
 /// Return true if the given value is known to be non-zero when defined. For
 /// vectors, return true if every demanded element is known to be non-zero when
 /// defined. For pointers, if the context instruction and dominator tree are
@@ -2454,22 +2479,9 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
   }
   // PHI
   else if (const 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.
-    BinaryOperator *BO = nullptr;
-    Value *Start = nullptr, *Step = nullptr;
-    const APInt *StartC, *StepC;
-    if (Q.IIQ.UseInstrInfo && matchSimpleRecurrence(PN, BO, Start, Step) &&
-        match(Start, m_APInt(StartC)) && match(Step, m_APInt(StepC))) {
-      if (BO->getOpcode() == Instruction::Add &&
-          (BO->hasNoUnsignedWrap() || BO->hasNoSignedWrap()) &&
-          StartC->isStrictlyPositive() && !StepC->isNegative())
-        return true;
-      if (BO->getOpcode() == Instruction::Mul &&
-          (BO->hasNoUnsignedWrap() || BO->hasNoSignedWrap()) &&
-          !StartC->isNullValue() && StepC->isStrictlyPositive())
-        return true;
-    }
+    if (Q.IIQ.UseInstrInfo && isNonZeroRecurrence(PN))
+      return true;
+
     // Check if all incoming values are non-zero using recursion.
     Query RecQ = Q;
     unsigned NewDepth = std::max(Depth, MaxAnalysisRecursionDepth - 1);

diff  --git a/llvm/test/Analysis/ValueTracking/monotonic-phi.ll b/llvm/test/Analysis/ValueTracking/monotonic-phi.ll
index 5b9abda25c71b..218cc222026b0 100644
--- a/llvm/test/Analysis/ValueTracking/monotonic-phi.ll
+++ b/llvm/test/Analysis/ValueTracking/monotonic-phi.ll
@@ -115,9 +115,7 @@ define i1 @test_add_nuw_negative_start(i8 %p, i8* %pq, i8 %n, i8 %r) {
 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
 ; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
 ; CHECK:       exit:
-; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[A]], [[R:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[ADD]], 0
-; CHECK-NEXT:    ret i1 [[CMP]]
+; CHECK-NEXT:    ret i1 false
 ;
 entry:
   br label %loop
@@ -292,8 +290,7 @@ define i1 @test_mul_nuw_negative_step(i8 %p, i8* %pq, i8 %n, i8 %r) {
 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
 ; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
 ; CHECK:       exit:
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A]], 0
-; CHECK-NEXT:    ret i1 [[CMP]]
+; CHECK-NEXT:    ret i1 false
 ;
 entry:
   br label %loop


        


More information about the llvm-commits mailing list