@@ -7728,41 +7728,33 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
77287728 }
77297729 }
77307730
7731- // When comparing results of sub and add instructions with identical operands,
7732- // optimization is valid when the comparison type and overflow flags satisfy:
7733- // - Signed comparisons (slt/sgt/sle/sge) require 'nsw' flags
7734- // - Unsigned comparisons (ult/ugt/ule/uge) require 'nuw' flags
7735- // - Equality comparisons (eq/ne) accept either 'nsw' or 'nuw'
7736- //
7737- // If conditions are met, the comparison simplifies to a zero comparison on
7738- // the second operand of the sub instruction with the swapped predicate.
7739- // Example transformation for signed comparison:
7740- // %sub = sub nsw i8 %x, %y
7741- // %add = add nsw i8 %x, %y
7742- // %cmp = icmp sgt i8 %sub, %add // (x - y) > (x + y)
7743- // becomes:
7744- // %cmp = icmp slt i8 %y, 0 // y < 0
7745- //
7746- // This handles similar cases to transform.
7731+ // icmp slt (sub nsw x, y), (add nsw x, y) --> icmp sgt y, 0
7732+ // icmp sgt (sub nsw x, y), (add nsw x, y) --> icmp slt y, 0
7733+ // icmp sle (sub nsw x, y), (add nsw x, y) --> icmp sge y, 0
7734+ // icmp sge (sub nsw x, y), (add nsw x, y) --> icmp sle y, 0
7735+ // icmp ult (sub nuw x, y), (add nuw x, y) --> icmp ugt y, 0
7736+ // icmp ugt (sub nuw x, y), (add nuw x, y) --> icmp ult y, 0
7737+ // icmp ule (sub nuw x, y), (add nuw x, y) --> icmp uge y, 0
7738+ // icmp uge (sub nuw x, y), (add nuw x, y) --> icmp ule y, 0
7739+ // icmp eq (sub nsw/nuw x, y), (add nsw/nuw x, y) --> icmp eq y, 0
7740+ // icmp ne (sub nsw/nuw x, y), (add nsw/nuw x, y) --> icmp ne y, 0
77477741 {
77487742 Value *A, *B;
7749- auto *I0 = dyn_cast<OverflowingBinaryOperator>(Op0);
7750- auto *I1 = dyn_cast<OverflowingBinaryOperator>(Op1);
7751- if (I0 && I1) {
7743+ CmpPredicate CmpPred;
7744+ if (match (&I, m_c_ICmp (CmpPred, m_Sub (m_Value (A), m_Value (B)),
7745+ m_c_Add (m_Deferred (A), m_Deferred (B))))) {
7746+ auto *I0 = cast<OverflowingBinaryOperator>(Op0);
7747+ auto *I1 = cast<OverflowingBinaryOperator>(Op1);
77527748 bool I0NUW = I0->hasNoUnsignedWrap ();
77537749 bool I1NUW = I1->hasNoUnsignedWrap ();
77547750 bool I0NSW = I0->hasNoSignedWrap ();
77557751 bool I1NSW = I1->hasNoSignedWrap ();
7756- bool UnsignedCmp = ICmpInst::isUnsigned (Pred);
7757- bool SignedCmp = ICmpInst::isSigned (Pred);
7758- bool EqualityCmp = ICmpInst::isEquality (Pred);
7759- CmpPredicate CmpPred;
7760- if ((UnsignedCmp && I0NUW && I1NUW) || (SignedCmp && I0NSW && I1NSW) ||
7761- (EqualityCmp && ((I0NUW || I0NSW) && (I1NUW || I1NSW)))) {
7762- if (match (&I, m_c_ICmp (CmpPred, m_Sub (m_Value (A), m_Value (B)),
7763- m_c_Add (m_Deferred (A), m_Deferred (B)))))
7764- return new ICmpInst (CmpPredicate::getSwapped (CmpPred), B,
7765- ConstantInt::get (Op0->getType (), 0 ));
7752+ if ((ICmpInst::isUnsigned (Pred) && I0NUW && I1NUW) ||
7753+ (ICmpInst::isSigned (Pred) && I0NSW && I1NSW) ||
7754+ (ICmpInst::isEquality (Pred) &&
7755+ ((I0NUW || I0NSW) && (I1NUW || I1NSW)))) {
7756+ return new ICmpInst (CmpPredicate::getSwapped (CmpPred), B,
7757+ ConstantInt::get (Op0->getType (), 0 ));
77667758 }
77677759 }
77687760 }
0 commit comments