aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Constants.cpp
diff options
context:
space:
mode:
authorChristopher Tetreault <ctetreau@quicinc.com>2020-07-07 13:16:00 -0700
committerChristopher Tetreault <ctetreau@quicinc.com>2020-07-07 13:45:51 -0700
commit021d56abb9ee3028cb88895144d71365e566c32f (patch)
tree2179803a88a79cc6bda6e064fe4e64d81790cec8 /llvm/lib/IR/Constants.cpp
parent23157f3bdb4f6af1d24aac7d4fbf439b71bba216 (diff)
downloadllvm-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.cpp21
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;
}