Skip to content

Commit

Permalink
[Analysis] Move DomConditionCache::findAffectedValues to a new file…
Browse files Browse the repository at this point in the history
…; NFC
  • Loading branch information
goldsteinn committed Mar 4, 2024
1 parent 10ccde3 commit 3bc0ff2
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 65 deletions.
7 changes: 7 additions & 0 deletions llvm/include/llvm/Analysis/ValueTracking.h
Original file line number Diff line number Diff line change
Expand Up @@ -1195,6 +1195,13 @@ std::optional<bool> 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<void(Value *)> InsertAffected);

} // end namespace llvm

#endif // LLVM_ANALYSIS_VALUETRACKING_H
68 changes: 3 additions & 65 deletions llvm/lib/Analysis/DomConditionCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Value *> &Affected) {
auto AddAffected = [&Affected](Value *V) {
if (isa<Argument>(V) || isa<GlobalValue>(V)) {
Affected.push_back(V);
} else if (auto *I = dyn_cast<Instruction>(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<Instruction>(Op) || isa<Argument>(Op))
Affected.push_back(Op);
}
}
};

SmallVector<Value *, 8> Worklist;
SmallPtrSet<Value *, 8> 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<Intrinsic::is_fpclass>(
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) {
Expand Down
69 changes: 69 additions & 0 deletions llvm/lib/Analysis/ValueTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9099,3 +9099,72 @@ ConstantRange llvm::computeConstantRange(const Value *V, bool ForSigned,

return CR;
}

static void
addValueAffectedByCondition(Value *V,
function_ref<void(Value *)> InsertAffected) {
assert(V != nullptr);
if (isa<Argument>(V) || isa<GlobalValue>(V)) {
InsertAffected(V);
} else if (auto *I = dyn_cast<Instruction>(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<Instruction>(Op) || isa<Argument>(Op))
InsertAffected(Op);
}
}
}

void llvm::findValuesAffectedByCondition(
Value *Cond, bool IsAssume, function_ref<void(Value *)> InsertAffected) {
auto AddAffected = [&InsertAffected](Value *V) {
addValueAffectedByCondition(V, InsertAffected);
};

assert(!IsAssume);
SmallVector<Value *, 8> Worklist;
SmallPtrSet<Value *, 8> 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<Intrinsic::is_fpclass>(
m_Value(A), m_Constant())))) {
// Handle patterns that computeKnownFPClass() support.
AddAffected(A);
}
}
}

0 comments on commit 3bc0ff2

Please sign in to comment.