aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorNoah Goldstein <goldstein.w.n@gmail.com>2024-02-26 16:30:39 -0600
committerNoah Goldstein <goldstein.w.n@gmail.com>2024-03-04 16:53:27 -0600
commitdb3bbe03f1c93100434a1394d293d13d4e5c1a2e (patch)
tree046afc528734506994b2e898e9793d1203481fe7 /llvm/lib/Analysis/ValueTracking.cpp
parent6ee46aba0695bd004e5b229b73dabe8fd5a70513 (diff)
downloadllvm-db3bbe03f1c93100434a1394d293d13d4e5c1a2e.zip
llvm-db3bbe03f1c93100434a1394d293d13d4e5c1a2e.tar.gz
llvm-db3bbe03f1c93100434a1394d293d13d4e5c1a2e.tar.bz2
[Analysis] Unify most of the tracking between AssumptionCache and DomConditionCache
This helps cover some missing cases in both and hopefully serves as creating an easier framework for extending general condition based analysis. Closes #83161
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp115
1 files changed, 60 insertions, 55 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index dd78c16..69b2710 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -9124,6 +9124,14 @@ void llvm::findValuesAffectedByCondition(
addValueAffectedByCondition(V, InsertAffected);
};
+ auto AddCmpOperands = [&AddAffected, IsAssume](Value *LHS, Value *RHS) {
+ if (IsAssume) {
+ AddAffected(LHS);
+ AddAffected(RHS);
+ } else if (match(RHS, m_Constant()))
+ AddAffected(LHS);
+ };
+
SmallVector<Value *, 8> Worklist;
SmallPtrSet<Value *, 8> Visited;
Worklist.push_back(Cond);
@@ -9135,65 +9143,62 @@ void llvm::findValuesAffectedByCondition(
CmpInst::Predicate Pred;
Value *A, *B, *X;
- if (IsAssume)
+ if (IsAssume) {
AddAffected(V);
+ if (match(V, m_Not(m_Value(X))))
+ AddAffected(X);
+ }
+
+ if (match(V, m_LogicalOp(m_Value(A), m_Value(B)))) {
+ // assume(A && B) is split to -> assume(A); assume(B);
+ // assume(!(A || B)) is split to -> assume(!A); assume(!B);
+ // Finally, assume(A || B) / assume(!(A && B)) generally don't provide
+ // enough information to be worth handling (intersection of information as
+ // opposed to union).
+ if (!IsAssume) {
+ Worklist.push_back(A);
+ Worklist.push_back(B);
+ }
+ } else if (match(V, m_ICmp(Pred, m_Value(A), m_Value(B)))) {
+ AddCmpOperands(A, B);
+
+ if (ICmpInst::isEquality(Pred)) {
+ if (match(B, m_ConstantInt())) {
+ // (X & C) or (X | C) or (X ^ C).
+ // (X << C) or (X >>_s C) or (X >>_u C).
+ if (match(A, m_BitwiseLogic(m_Value(X), m_ConstantInt())) ||
+ match(A, m_Shift(m_Value(X), m_ConstantInt())))
+ AddAffected(X);
+ }
+ } else {
+ // Handle (A + C1) u< C2, which is the canonical form of
+ // A > C3 && A < C4.
+ if (match(A, m_Add(m_Value(X), m_ConstantInt())) &&
+ match(B, m_ConstantInt()))
+ AddAffected(X);
+
+ // Handle icmp slt/sgt (bitcast X to int), 0/-1, which is supported
+ // by computeKnownFPClass().
+ if (match(A, m_ElementWiseBitCast(m_Value(X)))) {
+ if (Pred == ICmpInst::ICMP_SLT && match(B, m_Zero()))
+ InsertAffected(X);
+ else if (Pred == ICmpInst::ICMP_SGT && match(B, m_AllOnes()))
+ InsertAffected(X);
+ }
+ }
+ } else if (match(Cond, m_FCmp(Pred, m_Value(A), m_Value(B)))) {
+ AddCmpOperands(A, B);
- if (IsAssume && match(V, m_Not(m_Value(X))))
- AddAffected(X);
- if (!IsAssume && match(V, m_LogicalOp(m_Value(A), m_Value(B)))) {
- Worklist.push_back(A);
- Worklist.push_back(B);
- } else if (match(V, m_Cmp(Pred, m_Value(A), m_Value(B))) &&
- (IsAssume || isa<ICmpInst>(V))) {
- if (IsAssume || match(B, m_Constant())) {
+ // fcmp fneg(x), y
+ // fcmp fabs(x), y
+ // fcmp fneg(fabs(x)), y
+ if (match(A, m_FNeg(m_Value(A))))
+ AddAffected(A);
+ if (match(A, m_FAbs(m_Value(A))))
AddAffected(A);
- if (IsAssume)
- AddAffected(B);
-
- if (IsAssume ? (Pred == ICmpInst::ICMP_EQ)
- : ICmpInst::isEquality(Pred)) {
- if (match(B, m_ConstantInt())) {
- // (X & C) or (X | C) or (X ^ C).
- // (X << C) or (X >>_s C) or (X >>_u C).
- if (match(A, m_BitwiseLogic(m_Value(X), m_ConstantInt())) ||
- match(A, m_Shift(m_Value(X), m_ConstantInt())))
- AddAffected(X);
- }
- } else {
- if (Pred == ICmpInst::ICMP_NE)
- if (match(A, m_And(m_Value(X), m_Power2())) && match(B, m_Zero()))
- AddAffected(X);
-
- if (!IsAssume || Pred == ICmpInst::ICMP_ULT) {
- // Handle (A + C1) u< C2, which is the canonical form of
- // A > C3 && A < C4.
- if (match(A, m_Add(m_Value(X), m_ConstantInt())) &&
- match(B, m_ConstantInt()))
- AddAffected(X);
- }
- if (!IsAssume) {
- // Handle icmp slt/sgt (bitcast X to int), 0/-1, which is supported
- // by computeKnownFPClass().
- if ((Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGT) &&
- match(A, m_ElementWiseBitCast(m_Value(X))))
- InsertAffected(X);
- }
- if (IsAssume && CmpInst::isFPPredicate(Pred)) {
- // fcmp fneg(x), y
- // fcmp fabs(x), y
- // fcmp fneg(fabs(x)), y
- if (match(A, m_FNeg(m_Value(A))))
- AddAffected(A);
- if (match(A, m_FAbs(m_Value(A))))
- AddAffected(A);
- }
- }
- }
- } else if ((!IsAssume &&
- match(Cond, m_FCmp(Pred, m_Value(A), m_Constant()))) ||
- match(Cond, m_Intrinsic<Intrinsic::is_fpclass>(m_Value(A),
- m_Value(B)))) {
+ } else if (match(V, m_Intrinsic<Intrinsic::is_fpclass>(m_Value(A),
+ m_Value()))) {
// Handle patterns that computeKnownFPClass() support.
AddAffected(A);
}