@@ -7728,41 +7728,33 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
7728
7728
}
7729
7729
}
7730
7730
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
7747
7741
{
7748
7742
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);
7752
7748
bool I0NUW = I0->hasNoUnsignedWrap ();
7753
7749
bool I1NUW = I1->hasNoUnsignedWrap ();
7754
7750
bool I0NSW = I0->hasNoSignedWrap ();
7755
7751
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 ));
7766
7758
}
7767
7759
}
7768
7760
}
0 commit comments