[llvm] r309726 - [Value Tracking] Refactor and/or logic into helper. NFC.

Chad Rosier via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 1 12:22:36 PDT 2017


Author: mcrosier
Date: Tue Aug  1 12:22:36 2017
New Revision: 309726

URL: http://llvm.org/viewvc/llvm-project?rev=309726&view=rev
Log:
[Value Tracking] Refactor and/or logic into helper. NFC.

Modified:
    llvm/trunk/lib/Analysis/ValueTracking.cpp

Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=309726&r1=309725&r2=309726&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/ValueTracking.cpp Tue Aug  1 12:22:36 2017
@@ -4493,62 +4493,74 @@ static Optional<bool> isImpliedCondICmps
   return None;
 }
 
+/// Return true if LHS implies RHS is true.  Return false if LHS implies RHS is
+/// false.  Otherwise, return None if we can't infer anything.  We expect the
+/// RHS to be an icmp and the LHS to be an 'and' or an 'or' instruction.
+static Optional<bool> isImpliedCondAndOr(const BinaryOperator *LHS,
+                                         const ICmpInst *RHS,
+                                         const DataLayout &DL, bool LHSIsFalse,
+                                         unsigned Depth) {
+  // The LHS must be an 'or' or an 'and' instruction.
+  assert((LHS->getOpcode() == Instruction::And ||
+          LHS->getOpcode() == Instruction::Or) &&
+         "Expected LHS to be 'and' or 'or'.");
+
+  // The remaining tests are all recursive, so bail out if we hit the limit.
+  if (Depth == MaxDepth)
+    return None;
+
+  // If the result of an 'or' is false, then we know both legs of the 'or' are
+  // false.  Similarly, if the result of an 'and' is true, then we know both
+  // legs of the 'and' are true.
+  Value *ALHS, *ARHS;
+  if ((LHSIsFalse && match(LHS, m_Or(m_Value(ALHS), m_Value(ARHS)))) ||
+      (!LHSIsFalse && match(LHS, m_And(m_Value(ALHS), m_Value(ARHS))))) {
+    // FIXME: Make this non-recursion.
+    if (Optional<bool> Implication =
+            isImpliedCondition(ALHS, RHS, DL, LHSIsFalse, Depth + 1))
+      return Implication;
+    if (Optional<bool> Implication =
+            isImpliedCondition(ARHS, RHS, DL, LHSIsFalse, Depth + 1))
+      return Implication;
+    return None;
+  }
+  return None;
+}
+
 Optional<bool> llvm::isImpliedCondition(const Value *LHS, const Value *RHS,
                                         const DataLayout &DL, bool LHSIsFalse,
                                         unsigned Depth) {
-  // A mismatch occurs when we compare a scalar cmp to a vector cmp, for example.
+  // A mismatch occurs when we compare a scalar cmp to a vector cmp, for
+  // example.
   if (LHS->getType() != RHS->getType())
     return None;
 
   Type *OpTy = LHS->getType();
-  assert(OpTy->isIntOrIntVectorTy(1));
+  assert(OpTy->isIntOrIntVectorTy(1) && "Expected integer type only!");
 
   // LHS ==> RHS by definition
   if (LHS == RHS)
     return !LHSIsFalse;
 
+  // FIXME: Extending the code below to handle vectors.
   if (OpTy->isVectorTy())
-    // TODO: extending the code below to handle vectors
     return None;
-  assert(OpTy->isIntegerTy(1) && "implied by above");
 
-  // We expect the RHS to be an icmp.
-  if (!isa<ICmpInst>(RHS))
-    return None;
+  assert(OpTy->isIntegerTy(1) && "implied by above");
 
   // Both LHS and RHS are icmps.
-  if (isa<ICmpInst>(LHS))
-    return isImpliedCondICmps(cast<ICmpInst>(LHS), cast<ICmpInst>(RHS), DL,
-                              LHSIsFalse, Depth);
-
-  // The LHS can be an 'or' or an 'and' instruction.
-  const Instruction *LHSInst = dyn_cast<Instruction>(LHS);
-  if (!LHSInst)
-    return None;
-
-  switch (LHSInst->getOpcode()) {
-  default:
-    return None;
-  case Instruction::Or:
-  case Instruction::And: {
-    // The remaining tests are all recursive, so bail out if we hit the limit.
-    if (Depth == MaxDepth)
-      return None;
-    // If the result of an 'or' is false, then we know both legs of the 'or' are
-    // false.  Similarly, if the result of an 'and' is true, then we know both
-    // legs of the 'and' are true.
-    Value *ALHS, *ARHS;
-    if ((LHSIsFalse && match(LHS, m_Or(m_Value(ALHS), m_Value(ARHS)))) ||
-        (!LHSIsFalse && match(LHS, m_And(m_Value(ALHS), m_Value(ARHS))))) {
-      if (Optional<bool> Implication =
-              isImpliedCondition(ALHS, RHS, DL, LHSIsFalse, Depth + 1))
-        return Implication;
-      if (Optional<bool> Implication =
-              isImpliedCondition(ARHS, RHS, DL, LHSIsFalse, Depth + 1))
-        return Implication;
-      return None;
-    }
-    return None;
-  }
+  const ICmpInst *LHSCmp = dyn_cast<ICmpInst>(LHS);
+  const ICmpInst *RHSCmp = dyn_cast<ICmpInst>(RHS);
+  if (LHSCmp && RHSCmp)
+    return isImpliedCondICmps(LHSCmp, RHSCmp, DL, LHSIsFalse, Depth);
+
+  // The LHS should be an 'or' or an 'and' instruction.  We expect the RHS to be
+  // an icmp. FIXME: Add support for and/or on the RHS.
+  const BinaryOperator *LHSBO = dyn_cast<BinaryOperator>(LHS);
+  if (LHSBO && RHSCmp) {
+    if ((LHSBO->getOpcode() == Instruction::And ||
+         LHSBO->getOpcode() == Instruction::Or))
+      return isImpliedCondAndOr(LHSBO, RHSCmp, DL, LHSIsFalse, Depth);
   }
+  return None;
 }




More information about the llvm-commits mailing list