[llvm] [ValueTracking] For NUW, X + Y are not 0 if they are nonequal (PR #148101)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 10 19:15:51 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-analysis
@llvm/pr-subscribers-llvm-selectiondag
Author: AZero13 (AZero13)
<details>
<summary>Changes</summary>
In NUW, X + Y is not 0 if X and Y are nonequal.
---
Full diff: https://github.com/llvm/llvm-project/pull/148101.diff
2 Files Affected:
- (modified) llvm/lib/Analysis/ValueTracking.cpp (+13-2)
- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (+6-1)
``````````diff
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 21f844c4d2f45..154dce6f1dfd5 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -2833,19 +2833,27 @@ static bool isNonZeroAdd(const APInt &DemandedElts, const SimplifyQuery &Q,
if (matchOpWithOpEqZero(X, Y))
return true;
- if (NUW)
+ if (NUW) {
+ // X + Y != 0 if X != Y, and X + Y is NUW.
+ if (isKnownNonEqual(X, Y, DemandedElts, Q, Depth))
+ return true;
return isKnownNonZero(Y, DemandedElts, Q, Depth) ||
isKnownNonZero(X, DemandedElts, Q, Depth);
+ }
KnownBits XKnown = computeKnownBits(X, DemandedElts, Q, Depth);
KnownBits YKnown = computeKnownBits(Y, DemandedElts, Q, Depth);
// If X and Y are both non-negative (as signed values) then their sum is not
// zero unless both X and Y are zero.
- if (XKnown.isNonNegative() && YKnown.isNonNegative())
+ if (XKnown.isNonNegative() && YKnown.isNonNegative()) {
if (isKnownNonZero(Y, DemandedElts, Q, Depth) ||
isKnownNonZero(X, DemandedElts, Q, Depth))
return true;
+ // X + Y != 0 if X != Y, and X + Y are both nonnegative.
+ if (isKnownNonEqual(X, Y, DemandedElts, Q, Depth))
+ return true;
+ }
// If X and Y are both negative (as signed values) then their sum is not
// zero unless both X and Y equal INT_MIN.
@@ -2859,6 +2867,9 @@ static bool isNonZeroAdd(const APInt &DemandedElts, const SimplifyQuery &Q,
// to INT_MIN.
if (YKnown.One.intersects(Mask))
return true;
+ // X + Y != 0 because if they are not equal, they cannot both be INT_MIN.
+ if (isKnownNonEqual(X, Y, DemandedElts, Q, Depth))
+ return true;
}
// The sum of a non-negative number and a power of two is not zero.
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index c1356239ad206..bd17b1d570858 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6015,10 +6015,15 @@ bool SelectionDAG::isKnownNeverZero(SDValue Op, unsigned Depth) const {
break;
case ISD::ADD:
- if (Op->getFlags().hasNoUnsignedWrap())
+ if (Op->getFlags().hasNoUnsignedWrap()) {
if (isKnownNeverZero(Op.getOperand(1), Depth + 1) ||
isKnownNeverZero(Op.getOperand(0), Depth + 1))
return true;
+ std::optional<bool> ne =
+ KnownBits::ne(computeKnownBits(Op.getOperand(0), Depth + 1),
+ computeKnownBits(Op.getOperand(1), Depth + 1));
+ return ne && *ne;
+ }
// TODO: There are a lot more cases we can prove for add.
break;
``````````
</details>
https://github.com/llvm/llvm-project/pull/148101
More information about the llvm-commits
mailing list