diff options
author | Yingwei Zheng <dtcxzyw2333@gmail.com> | 2024-10-18 21:19:02 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-18 21:19:02 +0800 |
commit | c89d731c5dc48e34ec4d081fce7e0c94e212b2f0 (patch) | |
tree | fe08a1c77927e246e43c4efe97c762dcf23ce709 /llvm/lib/Analysis/LazyValueInfo.cpp | |
parent | 12bcea3292a1559ecad549b5d34c8abcf19f2626 (diff) | |
download | llvm-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.cpp | 14 |
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(); } |