diff options
author | Sanjay Patel <spatel@rotateright.com> | 2019-06-11 22:25:18 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2019-06-11 22:25:18 +0000 |
commit | 40e3bdf8764d4d6053305bd602832912da245cdf (patch) | |
tree | df43473d4bde24babc7020232ac680b753a323b9 /llvm/lib/Analysis/VectorUtils.cpp | |
parent | 898d48117430eac158fb3b01741ac4a3c63b4a4e (diff) | |
download | bcm5719-llvm-40e3bdf8764d4d6053305bd602832912da245cdf.tar.gz bcm5719-llvm-40e3bdf8764d4d6053305bd602832912da245cdf.zip |
[Analysis] add isSplatValue() for vectors in IR
We have the related getSplatValue() already in IR (see code just above the proposed addition).
But sometimes we only need to know that the value is a splat rather than capture the splatted
scalar value. Also, we have an isSplatValue() function already in SDAG.
Motivation - recent bugs that would potentially benefit from improved splat analysis in IR:
https://bugs.llvm.org/show_bug.cgi?id=37428
https://bugs.llvm.org/show_bug.cgi?id=42174
Differential Revision: https://reviews.llvm.org/D63138
llvm-svn: 363106
Diffstat (limited to 'llvm/lib/Analysis/VectorUtils.cpp')
-rw-r--r-- | llvm/lib/Analysis/VectorUtils.cpp | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/VectorUtils.cpp b/llvm/lib/Analysis/VectorUtils.cpp index ea00f0a7dd3..8040af12d7c 100644 --- a/llvm/lib/Analysis/VectorUtils.cpp +++ b/llvm/lib/Analysis/VectorUtils.cpp @@ -321,6 +321,45 @@ const llvm::Value *llvm::getSplatValue(const Value *V) { return nullptr; } +// This setting is based on its counterpart in value tracking, but it could be +// adjusted if needed. +const unsigned MaxDepth = 6; + +bool llvm::isSplatValue(const Value *V, unsigned Depth) { + assert(Depth <= MaxDepth && "Limit Search Depth"); + + if (isa<VectorType>(V->getType())) { + if (isa<UndefValue>(V)) + return true; + // FIXME: Constant splat analysis does not allow undef elements. + if (auto *C = dyn_cast<Constant>(V)) + return C->getSplatValue() != nullptr; + } + + // FIXME: Constant splat analysis does not allow undef elements. + Constant *Mask; + if (match(V, m_ShuffleVector(m_Value(), m_Value(), m_Constant(Mask)))) + return Mask->getSplatValue() != nullptr; + + // The remaining tests are all recursive, so bail out if we hit the limit. + if (Depth++ == MaxDepth) + return false; + + // If both operands of a binop are splats, the result is a splat. + Value *X, *Y, *Z; + if (match(V, m_BinOp(m_Value(X), m_Value(Y)))) + return isSplatValue(X, Depth) && isSplatValue(Y, Depth); + + // If all operands of a select are splats, the result is a splat. + if (match(V, m_Select(m_Value(X), m_Value(Y), m_Value(Z)))) + return isSplatValue(X, Depth) && isSplatValue(Y, Depth) && + isSplatValue(Z, Depth); + + // TODO: Add support for unary ops (fneg), casts, intrinsics (overflow ops). + + return false; +} + MapVector<Instruction *, uint64_t> llvm::computeMinimumValueSizes(ArrayRef<BasicBlock *> Blocks, DemandedBits &DB, const TargetTransformInfo *TTI) { |