diff options
author | Noah Goldstein <goldstein.w.n@gmail.com> | 2024-02-26 16:30:39 -0600 |
---|---|---|
committer | Noah Goldstein <goldstein.w.n@gmail.com> | 2024-03-04 16:53:27 -0600 |
commit | db3bbe03f1c93100434a1394d293d13d4e5c1a2e (patch) | |
tree | 046afc528734506994b2e898e9793d1203481fe7 /llvm/lib/Analysis/ValueTracking.cpp | |
parent | 6ee46aba0695bd004e5b229b73dabe8fd5a70513 (diff) | |
download | llvm-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.cpp | 115 |
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); } |