[llvm] [InstCombine] fold icmp with add/sub instructions having the same operands (PR #143241)
Acthinks Yang via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 9 03:07:00 PDT 2025
================
@@ -7728,6 +7728,45 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
}
}
+ // When comparing results of sub and add instructions with identical operands,
+ // optimization is valid when the comparison type and overflow flags satisfy:
+ // - Signed comparisons (slt/sgt/sle/sge) require 'nsw' flags
+ // - Unsigned comparisons (ult/ugt/ule/uge) require 'nuw' flags
+ // - Equality comparisons (eq/ne) accept either 'nsw' or 'nuw'
+ //
+ // If conditions are met, the comparison simplifies to a zero comparison on
+ // the second operand of the sub instruction with the swapped predicate.
+ // Example transformation for signed comparison:
+ // %sub = sub nsw i8 %x, %y
+ // %add = add nsw i8 %x, %y
+ // %cmp = icmp sgt i8 %sub, %add // (x - y) > (x + y)
+ // becomes:
+ // %cmp = icmp slt i8 %y, 0 // y < 0
+ //
+ // This handles similar cases to transform.
+ {
+ Value *A, *B;
+ auto *I0 = dyn_cast<OverflowingBinaryOperator>(Op0);
+ auto *I1 = dyn_cast<OverflowingBinaryOperator>(Op1);
+ if (I0 && I1) {
+ bool I0NUW = I0->hasNoUnsignedWrap();
+ bool I1NUW = I1->hasNoUnsignedWrap();
+ bool I0NSW = I0->hasNoSignedWrap();
+ bool I1NSW = I1->hasNoSignedWrap();
+ bool UnsignedCmp = ICmpInst::isUnsigned(Pred);
+ bool SignedCmp = ICmpInst::isSigned(Pred);
+ bool EqualityCmp = ICmpInst::isEquality(Pred);
----------------
Acthinks wrote:
done
https://github.com/llvm/llvm-project/pull/143241
More information about the llvm-commits
mailing list