diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h index f0d0ee554f12b..9cfb7af9dba0d 100644 --- a/llvm/include/llvm/Analysis/ValueTracking.h +++ b/llvm/include/llvm/Analysis/ValueTracking.h @@ -1195,6 +1195,13 @@ std::optional isImpliedByDomCondition(CmpInst::Predicate Pred, const Value *LHS, const Value *RHS, const Instruction *ContextI, const DataLayout &DL); + +/// Call \p InsertAffected on all Values whose known bits / value may be +/// affected by the condition \p Cond. Used by AssumptionCache and +/// DomConditionCache. +void findValuesAffectedByCondition(Value *Cond, bool IsAssume, + function_ref InsertAffected); + } // end namespace llvm #endif // LLVM_ANALYSIS_VALUETRACKING_H diff --git a/llvm/lib/Analysis/DomConditionCache.cpp b/llvm/lib/Analysis/DomConditionCache.cpp index da05e02b4b57f..66bd15b47901d 100644 --- a/llvm/lib/Analysis/DomConditionCache.cpp +++ b/llvm/lib/Analysis/DomConditionCache.cpp @@ -7,75 +7,13 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/DomConditionCache.h" -#include "llvm/IR/PatternMatch.h" - +#include "llvm/Analysis/ValueTracking.h" using namespace llvm; -using namespace llvm::PatternMatch; -// TODO: This code is very similar to findAffectedValues() in -// AssumptionCache, but currently specialized to just the patterns that -// computeKnownBits() supports, and without the notion of result elem indices -// that are AC specific. Deduplicate this code once we have a clearer picture -// of how much they can be shared. static void findAffectedValues(Value *Cond, SmallVectorImpl &Affected) { - auto AddAffected = [&Affected](Value *V) { - if (isa(V) || isa(V)) { - Affected.push_back(V); - } else if (auto *I = dyn_cast(V)) { - Affected.push_back(I); - - // Peek through unary operators to find the source of the condition. - Value *Op; - if (match(I, m_PtrToInt(m_Value(Op)))) { - if (isa(Op) || isa(Op)) - Affected.push_back(Op); - } - } - }; - - SmallVector Worklist; - SmallPtrSet Visited; - Worklist.push_back(Cond); - while (!Worklist.empty()) { - Value *V = Worklist.pop_back_val(); - if (!Visited.insert(V).second) - continue; - - CmpInst::Predicate Pred; - Value *A, *B; - if (match(V, m_LogicalOp(m_Value(A), m_Value(B)))) { - Worklist.push_back(A); - Worklist.push_back(B); - } else if (match(V, m_ICmp(Pred, m_Value(A), m_Constant()))) { - AddAffected(A); - - if (ICmpInst::isEquality(Pred)) { - Value *X; - // (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 { - Value *X; - // 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()))) - AddAffected(X); - // 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)))) - Affected.push_back(X); - } - } else if (match(Cond, m_CombineOr(m_FCmp(Pred, m_Value(A), m_Constant()), - m_Intrinsic( - m_Value(A), m_Constant())))) { - // Handle patterns that computeKnownFPClass() support. - AddAffected(A); - } - } + auto InsertAffected = [&Affected](Value *V) { Affected.push_back(V); }; + findValuesAffectedByCondition(Cond, /*IsAssume=*/false, InsertAffected); } void DomConditionCache::registerBranch(BranchInst *BI) { diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index e591ac504e9f0..4b230863b1672 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -9099,3 +9099,72 @@ ConstantRange llvm::computeConstantRange(const Value *V, bool ForSigned, return CR; } + +static void +addValueAffectedByCondition(Value *V, + function_ref InsertAffected) { + assert(V != nullptr); + if (isa(V) || isa(V)) { + InsertAffected(V); + } else if (auto *I = dyn_cast(V)) { + InsertAffected(V); + + // Peek through unary operators to find the source of the condition. + Value *Op; + if (match(I, m_PtrToInt(m_Value(Op)))) { + if (isa(Op) || isa(Op)) + InsertAffected(Op); + } + } +} + +void llvm::findValuesAffectedByCondition( + Value *Cond, bool IsAssume, function_ref InsertAffected) { + auto AddAffected = [&InsertAffected](Value *V) { + addValueAffectedByCondition(V, InsertAffected); + }; + + assert(!IsAssume); + SmallVector Worklist; + SmallPtrSet Visited; + Worklist.push_back(Cond); + while (!Worklist.empty()) { + Value *V = Worklist.pop_back_val(); + if (!Visited.insert(V).second) + continue; + + CmpInst::Predicate Pred; + Value *A, *B; + if (match(V, m_LogicalOp(m_Value(A), m_Value(B)))) { + Worklist.push_back(A); + Worklist.push_back(B); + } else if (match(V, m_ICmp(Pred, m_Value(A), m_Constant()))) { + AddAffected(A); + + if (ICmpInst::isEquality(Pred)) { + Value *X; + // (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 { + Value *X; + // 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()))) + AddAffected(X); + // 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); + } + } else if (match(Cond, m_CombineOr(m_FCmp(Pred, m_Value(A), m_Constant()), + m_Intrinsic( + m_Value(A), m_Constant())))) { + // Handle patterns that computeKnownFPClass() support. + AddAffected(A); + } + } +}