[llvm] r266987 - Refactor implied condition logic from ValueTracking directly into CmpInst. NFC.

Chad Rosier via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 21 07:04:56 PDT 2016


Author: mcrosier
Date: Thu Apr 21 09:04:54 2016
New Revision: 266987

URL: http://llvm.org/viewvc/llvm-project?rev=266987&view=rev
Log:
Refactor implied condition logic from ValueTracking directly into CmpInst. NFC.

Differential Revision: http://reviews.llvm.org/D19330

Modified:
    llvm/trunk/include/llvm/IR/InstrTypes.h
    llvm/trunk/lib/Analysis/ValueTracking.cpp
    llvm/trunk/lib/IR/Instructions.cpp

Modified: llvm/trunk/include/llvm/IR/InstrTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/InstrTypes.h?rev=266987&r1=266986&r2=266987&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/InstrTypes.h (original)
+++ llvm/trunk/include/llvm/IR/InstrTypes.h Thu Apr 21 09:04:54 2016
@@ -1067,6 +1067,18 @@ public:
     return isFalseWhenEqual(getPredicate());
   }
 
+  /// @brief Determine if Pred1 implies Pred2 is true when two compares have
+  /// matching operands.
+  bool isTrueWhenOperandsMatch(Predicate Pred2) {
+    return isTrueWhenOperandsMatch(getPredicate(), Pred2);
+  }
+
+  /// @brief Determine if Pred1 implies Pred2 is false when two compares have
+  /// matching operands.
+  bool isFalseWhenOperandsMatch(Predicate Pred2) {
+    return isFalseWhenOperandsMatch(getPredicate(), Pred2);
+  }
+
   /// @returns true if the predicate is unsigned, false otherwise.
   /// @brief Determine if the predicate is an unsigned operation.
   static bool isUnsigned(Predicate predicate);
@@ -1087,6 +1099,14 @@ public:
   /// Determine if the predicate is false when comparing a value with itself.
   static bool isFalseWhenEqual(Predicate predicate);
 
+  /// Determine if Pred1 implies Pred2 is true when two compares have matching
+  /// operands.
+  static bool isTrueWhenOperandsMatch(Predicate Pred1, Predicate Pred2);
+
+  /// Determine if Pred1 implies Pred2 is false when two compares have matching
+  /// operands.
+  static bool isFalseWhenOperandsMatch(Predicate Pred1, Predicate Pred2);
+
   /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
   static inline bool classof(const Instruction *I) {
     return I->getOpcode() == Instruction::ICmp ||

Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=266987&r1=266986&r2=266987&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/ValueTracking.cpp Thu Apr 21 09:04:54 2016
@@ -3935,61 +3935,11 @@ static Optional<bool> isImpliedCondMatch
     std::swap(BLHS, BRHS);
     BPred = ICmpInst::getSwappedPredicate(BPred);
   }
-
-  // If the predicates match, then we know the first condition implies the
-  // second is true.
-  if (APred == BPred)
+  if (CmpInst::isTrueWhenOperandsMatch(APred, BPred))
     return true;
-
-  // If an inverted APred matches BPred, we can infer the second condition is
-  // false.
-  if (CmpInst::getInversePredicate(APred) == BPred)
+  if (CmpInst::isFalseWhenOperandsMatch(APred, BPred))
     return false;
 
-  // If a swapped APred matches BPred, we can infer the second condition is
-  // false in many cases.
-  if (CmpInst::getSwappedPredicate(APred) == BPred) {
-    switch (APred) {
-    default:
-      break;
-    case CmpInst::ICMP_UGT: // A >u B implies A <u B is false.
-    case CmpInst::ICMP_ULT: // A <u B implies A >u B is false.
-    case CmpInst::ICMP_SGT: // A >s B implies A <s B is false.
-    case CmpInst::ICMP_SLT: // A <s B implies A >s B is false.
-      return false;
-    }
-  }
-
-  // The predicates must match sign or at least one of them must be an equality
-  // comparison (which is signless).
-  if (ICmpInst::isSigned(APred) != ICmpInst::isSigned(BPred) &&
-      !ICmpInst::isEquality(APred) && !ICmpInst::isEquality(BPred))
-    return None;
-
-  switch (APred) {
-  default:
-    break;
-  case CmpInst::ICMP_EQ:
-    // A == B implies A > B and A < B are false.
-    if (CmpInst::isFalseWhenEqual(BPred))
-      return false;
-
-    break;
-  case CmpInst::ICMP_UGT:
-  case CmpInst::ICMP_ULT:
-  case CmpInst::ICMP_SGT:
-  case CmpInst::ICMP_SLT:
-    // A > B implies A == B is false.
-    // A < B implies A == B is false.
-    if (BPred == CmpInst::ICMP_EQ)
-      return false;
-
-    // A > B implies A != B is true.
-    // A < B implies A != B is true.
-    if (BPred == CmpInst::ICMP_NE)
-      return true;
-    break;
-  }
   return None;
 }
 

Modified: llvm/trunk/lib/IR/Instructions.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Instructions.cpp?rev=266987&r1=266986&r2=266987&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Instructions.cpp (original)
+++ llvm/trunk/lib/IR/Instructions.cpp Thu Apr 21 09:04:54 2016
@@ -3597,6 +3597,58 @@ bool CmpInst::isFalseWhenEqual(Predicate
   }
 }
 
+bool CmpInst::isTrueWhenOperandsMatch(Predicate Pred1, Predicate Pred2) {
+  // If the predicates match, then we know the first condition implies the
+  // second is true.
+  if (Pred1 == Pred2)
+    return true;
+
+  switch (Pred1) {
+  default:
+    break;
+  case ICMP_UGT: // A >u B implies A != B is true.
+  case ICMP_ULT: // A <u B implies A != B is true.
+  case ICMP_SGT: // A >s B implies A != B is true.
+  case ICMP_SLT: // A <s B implies A != B is true.
+    return Pred2 == ICMP_NE;
+  }
+  return false;
+}
+
+bool CmpInst::isFalseWhenOperandsMatch(Predicate Pred1, Predicate Pred2) {
+  // If an inverted Pred1 matches Pred2, we can infer the second condition is
+  // false.
+  if (getInversePredicate(Pred1) == Pred2)
+    return true;
+
+  // If a swapped Pred1 matches Pred2, we can infer the second condition is
+  // false in many cases.
+  if (getSwappedPredicate(Pred1) == Pred2) {
+    switch (Pred1) {
+    default:
+      break;
+    case ICMP_UGT: // A >u B implies A <u B is false.
+    case ICMP_ULT: // A <u B implies A >u B is false.
+    case ICMP_SGT: // A >s B implies A <s B is false.
+    case ICMP_SLT: // A <s B implies A >s B is false.
+      return true;
+    }
+  }
+  // A == B implies A > B and A < B are false.
+  if (Pred1 == ICMP_EQ && isFalseWhenEqual(Pred2))
+    return true;
+
+  switch (Pred1) {
+  default:
+    break;
+  case ICMP_UGT: // A >u B implies A == B is false.
+  case ICMP_ULT: // A <u B implies A == B is false.
+  case ICMP_SGT: // A >s B implies A == B is false.
+  case ICMP_SLT: // A <s B implies A == B is false.
+    return Pred2 == ICMP_EQ;
+  }
+  return false;
+}
 
 //===----------------------------------------------------------------------===//
 //                        SwitchInst Implementation




More information about the llvm-commits mailing list