aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2021-03-21 18:36:20 +0100
committerNikita Popov <nikita.ppv@gmail.com>2021-03-21 18:41:35 +0100
commitd11d5d1c5f5a8bafc28be98f43c15a3452abb98b (patch)
treef538998ce6cf1e3b2771687b767d36a43f23fe56 /llvm/lib/Analysis/ValueTracking.cpp
parentf5bbdf2a674a94c568aaa7dca4c282901256683b (diff)
downloadllvm-d11d5d1c5f5a8bafc28be98f43c15a3452abb98b.zip
llvm-d11d5d1c5f5a8bafc28be98f43c15a3452abb98b.tar.gz
llvm-d11d5d1c5f5a8bafc28be98f43c15a3452abb98b.tar.bz2
[ValueTracking] Improve mul handling in isKnownNonEqual()
X != X * C is true if: * C is not 0 or 1 * X is not 0 * mul is nsw or nuw Proof: https://alive2.llvm.org/ce/z/uwF29z This is motivated by one of the cases in D98422.
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp16
1 files changed, 16 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 79399cf..b2f105f 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -2530,6 +2530,19 @@ static bool isAddOfNonZero(const Value *V1, const Value *V2, unsigned Depth,
return isKnownNonZero(Op, Depth + 1, Q);
}
+/// Return true if V2 == V1 * C, where V1 is known non-zero, C is not 0/1 and
+/// the multiplication is nuw or nsw.
+static bool isNonEqualMul(const Value *V1, const Value *V2, unsigned Depth,
+ const Query &Q) {
+ if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(V2)) {
+ const APInt *C;
+ return match(OBO, m_Mul(m_Specific(V1), m_APInt(C))) &&
+ (OBO->hasNoUnsignedWrap() || OBO->hasNoSignedWrap()) &&
+ !C->isNullValue() && !C->isOneValue() &&
+ isKnownNonZero(V1, Depth + 1, Q);
+ }
+ return false;
+}
/// Return true if it is known that V1 != V2.
static bool isKnownNonEqual(const Value *V1, const Value *V2, unsigned Depth,
@@ -2591,6 +2604,9 @@ static bool isKnownNonEqual(const Value *V1, const Value *V2, unsigned Depth,
if (isAddOfNonZero(V1, V2, Depth, Q) || isAddOfNonZero(V2, V1, Depth, Q))
return true;
+ if (isNonEqualMul(V1, V2, Depth, Q) || isNonEqualMul(V2, V1, Depth, Q))
+ return true;
+
if (V1->getType()->isIntOrIntVectorTy()) {
// Are any known bits in V1 contradictory to known bits in V2? If V1
// has a known zero where V2 has a known one, they must not be equal.