diff options
author | Christopher Tetreault <ctetreau@quicinc.com> | 2020-07-07 13:16:00 -0700 |
---|---|---|
committer | Christopher Tetreault <ctetreau@quicinc.com> | 2020-07-07 13:45:51 -0700 |
commit | 021d56abb9ee3028cb88895144d71365e566c32f (patch) | |
tree | 2179803a88a79cc6bda6e064fe4e64d81790cec8 /llvm/lib/IR/Constants.cpp | |
parent | 23157f3bdb4f6af1d24aac7d4fbf439b71bba216 (diff) | |
download | llvm-021d56abb9ee3028cb88895144d71365e566c32f.zip llvm-021d56abb9ee3028cb88895144d71365e566c32f.tar.gz llvm-021d56abb9ee3028cb88895144d71365e566c32f.tar.bz2 |
[SVE] Make Constant::getSplatValue work for scalable vector splats
Summary:
Make Constant::getSplatValue recognize scalable vector splats of the
form created by ConstantVector::getSplat. Add unit test to verify that
C == ConstantVector::getSplat(C)->getSplatValue() for fixed width and
scalable vector splats
Reviewers: efriedma, spatel, fpetrogalli, c-rhodes
Reviewed By: efriedma
Subscribers: sdesmalen, tschuett, hiraditya, rkruppe, psnobl, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D82416
Diffstat (limited to 'llvm/lib/IR/Constants.cpp')
-rw-r--r-- | llvm/lib/IR/Constants.cpp | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index d8e044e..cbbcca2 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -1585,6 +1585,27 @@ Constant *Constant::getSplatValue(bool AllowUndefs) const { return CV->getSplatValue(); if (const ConstantVector *CV = dyn_cast<ConstantVector>(this)) return CV->getSplatValue(AllowUndefs); + + // Check if this is a constant expression splat of the form returned by + // ConstantVector::getSplat() + const auto *Shuf = dyn_cast<ConstantExpr>(this); + if (Shuf && Shuf->getOpcode() == Instruction::ShuffleVector && + isa<UndefValue>(Shuf->getOperand(1))) { + + const auto *IElt = dyn_cast<ConstantExpr>(Shuf->getOperand(0)); + if (IElt && IElt->getOpcode() == Instruction::InsertElement && + isa<UndefValue>(IElt->getOperand(0))) { + + ArrayRef<int> Mask = Shuf->getShuffleMask(); + Constant *SplatVal = IElt->getOperand(1); + ConstantInt *Index = dyn_cast<ConstantInt>(IElt->getOperand(2)); + + if (Index && Index->getValue() == 0 && + std::all_of(Mask.begin(), Mask.end(), [](int I) { return I == 0; })) + return SplatVal; + } + } + return nullptr; } |