Skip to content

Commit dc653c4

Browse files
committed
[ValueTracking] For NUW, X + Y are not 0 if they are nonequal
In NUW, X + Y is not 0 if X and Y are nonequal.
1 parent a8280c4 commit dc653c4

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2833,19 +2833,27 @@ static bool isNonZeroAdd(const APInt &DemandedElts, const SimplifyQuery &Q,
28332833
if (matchOpWithOpEqZero(X, Y))
28342834
return true;
28352835

2836-
if (NUW)
2836+
if (NUW) {
2837+
// X + Y != 0 if X != Y, and X + Y is NUW.
2838+
if (isKnownNonEqual(X, Y, DemandedElts, Q, Depth))
2839+
return true;
28372840
return isKnownNonZero(Y, DemandedElts, Q, Depth) ||
28382841
isKnownNonZero(X, DemandedElts, Q, Depth);
2842+
}
28392843

28402844
KnownBits XKnown = computeKnownBits(X, DemandedElts, Q, Depth);
28412845
KnownBits YKnown = computeKnownBits(Y, DemandedElts, Q, Depth);
28422846

28432847
// If X and Y are both non-negative (as signed values) then their sum is not
28442848
// zero unless both X and Y are zero.
2845-
if (XKnown.isNonNegative() && YKnown.isNonNegative())
2849+
if (XKnown.isNonNegative() && YKnown.isNonNegative()) {
28462850
if (isKnownNonZero(Y, DemandedElts, Q, Depth) ||
28472851
isKnownNonZero(X, DemandedElts, Q, Depth))
28482852
return true;
2853+
// X + Y != 0 if X != Y, and X + Y are both nonnegative.
2854+
if (isKnownNonEqual(X, Y, DemandedElts, Q, Depth))
2855+
return true;
2856+
}
28492857

28502858
// If X and Y are both negative (as signed values) then their sum is not
28512859
// zero unless both X and Y equal INT_MIN.
@@ -2859,6 +2867,9 @@ static bool isNonZeroAdd(const APInt &DemandedElts, const SimplifyQuery &Q,
28592867
// to INT_MIN.
28602868
if (YKnown.One.intersects(Mask))
28612869
return true;
2870+
// X + Y != 0 because if they are not equal, they cannot both be INT_MIN.
2871+
if (isKnownNonEqual(X, Y, DemandedElts, Q, Depth))
2872+
return true;
28622873
}
28632874

28642875
// The sum of a non-negative number and a power of two is not zero.

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6015,10 +6015,15 @@ bool SelectionDAG::isKnownNeverZero(SDValue Op, unsigned Depth) const {
60156015
break;
60166016

60176017
case ISD::ADD:
6018-
if (Op->getFlags().hasNoUnsignedWrap())
6018+
if (Op->getFlags().hasNoUnsignedWrap()) {
60196019
if (isKnownNeverZero(Op.getOperand(1), Depth + 1) ||
60206020
isKnownNeverZero(Op.getOperand(0), Depth + 1))
60216021
return true;
6022+
std::optional<bool> ne =
6023+
KnownBits::ne(computeKnownBits(Op.getOperand(0), Depth + 1),
6024+
computeKnownBits(Op.getOperand(1), Depth + 1));
6025+
return ne && *ne;
6026+
}
60226027
// TODO: There are a lot more cases we can prove for add.
60236028
break;
60246029

0 commit comments

Comments
 (0)