Index: include/llvm/IR/InstrTypes.h =================================================================== --- include/llvm/IR/InstrTypes.h +++ include/llvm/IR/InstrTypes.h @@ -1067,6 +1067,18 @@ 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 @@ /// 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 || Index: lib/Analysis/ValueTracking.cpp =================================================================== --- lib/Analysis/ValueTracking.cpp +++ lib/Analysis/ValueTracking.cpp @@ -3955,61 +3955,11 @@ 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_SGT: // 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; } Index: lib/IR/Instructions.cpp =================================================================== --- lib/IR/Instructions.cpp +++ lib/IR/Instructions.cpp @@ -3597,6 +3597,58 @@ } } +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 s B implies A != B is true. + case ICMP_SLT: // A u B implies A u B is false. + case ICMP_SGT: // 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 s B implies A == B is false. + case ICMP_SLT: // A