diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index edbeede910d7f..651628e404b7a 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -8471,26 +8471,12 @@ isImpliedCondOperands(CmpInst::Predicate Pred, const Value *ALHS, } } -/// Return true if the operands of two compares (expanded as "L0 pred L1" and -/// "R0 pred R1") match. IsSwappedOps is true when the operands match, but are -/// swapped. -static bool areMatchingOperands(const Value *L0, const Value *L1, const Value *R0, - const Value *R1, bool &AreSwappedOps) { - bool AreMatchingOps = (L0 == R0 && L1 == R1); - AreSwappedOps = (L0 == R1 && L1 == R0); - return AreMatchingOps || AreSwappedOps; -} - /// Return true if "icmp1 LPred X, Y" implies "icmp2 RPred X, Y" is true. /// Return false if "icmp1 LPred X, Y" implies "icmp2 RPred X, Y" is false. /// Otherwise, return std::nullopt if we can't infer anything. static std::optional isImpliedCondMatchingOperands(CmpInst::Predicate LPred, - CmpInst::Predicate RPred, bool AreSwappedOps) { - // Canonicalize the predicate as if the operands were not commuted. - if (AreSwappedOps) - RPred = ICmpInst::getSwappedPredicate(RPred); - + CmpInst::Predicate RPred) { if (CmpInst::isImpliedTrueByMatchingCmp(LPred, RPred)) return true; if (CmpInst::isImpliedFalseByMatchingCmp(LPred, RPred)) @@ -8532,6 +8518,25 @@ static std::optional isImpliedCondICmps(const ICmpInst *LHS, CmpInst::Predicate LPred = LHSIsTrue ? LHS->getPredicate() : LHS->getInversePredicate(); + // We can have non-canonical operands, so try to normalize any common operand + // to L0/R0. + if (L0 == R1) { + std::swap(R0, R1); + RPred = ICmpInst::getSwappedPredicate(RPred); + } + if (R0 == L1) { + std::swap(L0, L1); + LPred = ICmpInst::getSwappedPredicate(LPred); + } + if (L1 == R1) { + // If we have L0 == R0 and L1 == R1, then make L1/R1 the constants. + if (L0 != R0 || match(L0, m_ImmConstant())) { + std::swap(L0, L1); + LPred = ICmpInst::getSwappedPredicate(LPred); + std::swap(R0, R1); + RPred = ICmpInst::getSwappedPredicate(RPred); + } + } // Can we infer anything when the 0-operands match and the 1-operands are // constants (not necessarily matching)? const APInt *LC, *RC; @@ -8539,32 +8544,15 @@ static std::optional isImpliedCondICmps(const ICmpInst *LHS, return isImpliedCondCommonOperandWithConstants(LPred, *LC, RPred, *RC); // Can we infer anything when the two compares have matching operands? - bool AreSwappedOps; - if (areMatchingOperands(L0, L1, R0, R1, AreSwappedOps)) - return isImpliedCondMatchingOperands(LPred, RPred, AreSwappedOps); + if (L0 == R0 && L1 == R1) + return isImpliedCondMatchingOperands(LPred, RPred); // L0 = R0 = L1 + R1, L0 >=u L1 implies R0 >=u R1, L0