[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:21 PDT 2025
https://github.com/AZero13 created https://github.com/llvm/llvm-project/pull/148101
In NUW, X + Y is not 0 if X and Y are nonequal.
>From dc653c4466b6b188af18fb39d6249ebe6548d9e0 Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Thu, 10 Jul 2025 22:05:10 -0400
Subject: [PATCH] [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.
---
llvm/lib/Analysis/ValueTracking.cpp | 15 +++++++++++++--
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 7 ++++++-
2 files changed, 19 insertions(+), 3 deletions(-)
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;
More information about the llvm-commits
mailing list