aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/LazyValueInfo.cpp
diff options
context:
space:
mode:
authorYingwei Zheng <dtcxzyw2333@gmail.com>2024-10-18 21:19:02 +0800
committerGitHub <noreply@github.com>2024-10-18 21:19:02 +0800
commitc89d731c5dc48e34ec4d081fce7e0c94e212b2f0 (patch)
treefe08a1c77927e246e43c4efe97c762dcf23ce709 /llvm/lib/Analysis/LazyValueInfo.cpp
parent12bcea3292a1559ecad549b5d34c8abcf19f2626 (diff)
downloadllvm-c89d731c5dc48e34ec4d081fce7e0c94e212b2f0.zip
llvm-c89d731c5dc48e34ec4d081fce7e0c94e212b2f0.tar.gz
llvm-c89d731c5dc48e34ec4d081fce7e0c94e212b2f0.tar.bz2
[LVI] Infer non-zero from equality icmp (#112838)
This following pattern is common in loop headers: ``` %101 = sub nuw i64 %78, %98 %103 = icmp eq i64 %78, %98 br i1 %103, label %.thread.i.i, label %.preheader.preheader.i.i .preheader.preheader.i.i: %invariant.umin.i.i = call i64 @llvm.umin.i64(i64 %101, i64 9) %umax.i = call i64 @llvm.umax.i64(i64 %invariant.umin.i.i, i64 1) br label %.preheader.i.i .preheader.i.i: ... %116 = add nuw nsw i64 %.011.i.i, 1 %exitcond.not.i = icmp eq i64 %116, %umax.i br i1 %exitcond.not.i, label %.critedge.i.i, label %.preheader.i.i ``` As `%78` is not equal to `%98` in BB `.preheader.preheader.i.i`, we can prove `%101` is non-zero. Then we can simplify the loop exit condition. Addresses regression introduced by https://github.com/llvm/llvm-project/pull/112742.
Diffstat (limited to 'llvm/lib/Analysis/LazyValueInfo.cpp')
-rw-r--r--llvm/lib/Analysis/LazyValueInfo.cpp14
1 files changed, 14 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index 10ad470..42b04046 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -1188,6 +1188,20 @@ std::optional<ValueLatticeElement> LazyValueInfoImpl::getValueFromICmpCondition(
return ValueLatticeElement::getRange(*CR);
}
+ // a - b or ptrtoint(a) - ptrtoint(b) ==/!= 0 if a ==/!= b
+ Value *X, *Y;
+ if (ICI->isEquality() && match(Val, m_Sub(m_Value(X), m_Value(Y)))) {
+ // Peek through ptrtoints
+ match(X, m_PtrToIntSameSize(DL, m_Value(X)));
+ match(Y, m_PtrToIntSameSize(DL, m_Value(Y)));
+ if ((X == LHS && Y == RHS) || (X == RHS && Y == LHS)) {
+ Constant *NullVal = Constant::getNullValue(Val->getType());
+ if (EdgePred == ICmpInst::ICMP_EQ)
+ return ValueLatticeElement::get(NullVal);
+ return ValueLatticeElement::getNot(NullVal);
+ }
+ }
+
return ValueLatticeElement::getOverdefined();
}