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 @@ -3807,35 +3807,16 @@ 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)) { ImpliedTrue = true; 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)) { ImpliedTrue = false; return true; } - // 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. - ImpliedTrue = false; - return true; - } - } - // 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) && Index: lib/IR/Instructions.cpp =================================================================== --- lib/IR/Instructions.cpp +++ lib/IR/Instructions.cpp @@ -3597,6 +3597,33 @@ } } +bool CmpInst::isTrueWhenOperandsMatch(Predicate Pred1, Predicate Pred2) { + // If the predicates match, then we know the first condition implies the + // second is true. + return Pred1 == Pred2; +} + +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_SGT: // A >s B implies A s B is false. + return true; + } + } + return false; +} //===----------------------------------------------------------------------===// // SwitchInst Implementation