aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Instructions.cpp
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2018-08-30 15:05:38 +0000
committerSanjay Patel <spatel@rotateright.com>2018-08-30 15:05:38 +0000
commitac619a09ecb228834c200afbae4a4d7aeaa5576a (patch)
tree76dbf7a17219085de847c599d415de9408f13adc /llvm/lib/IR/Instructions.cpp
parentba3334a25f8a885d2f4d91fe1374ecd6a0ea83b2 (diff)
downloadllvm-ac619a09ecb228834c200afbae4a4d7aeaa5576a.zip
llvm-ac619a09ecb228834c200afbae4a4d7aeaa5576a.tar.gz
llvm-ac619a09ecb228834c200afbae4a4d7aeaa5576a.tar.bz2
[IR] add shuffle queries for identity extend/extract
This was one of the potential follow-ups suggested in D48236, and these will be used to make matching the patterns in PR38691 cleaner: https://bugs.llvm.org/show_bug.cgi?id=38691 About the vocabulary: in the DAG, these would be concat_vector with an undef operand or extract_subvector. Alternate names are discussed in the review, but I think these are familiar/good enough to proceed. Once we have uses of them in code, we might adjust if there are better options. https://reviews.llvm.org/D51392 llvm-svn: 341075
Diffstat (limited to 'llvm/lib/IR/Instructions.cpp')
-rw-r--r--llvm/lib/IR/Instructions.cpp57
1 files changed, 48 insertions, 9 deletions
diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index 1a2752d..2bf9f0b 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -1660,17 +1660,17 @@ void ShuffleVectorInst::getShuffleMask(const Constant *Mask,
}
}
-bool ShuffleVectorInst::isSingleSourceMask(ArrayRef<int> Mask) {
+static bool isSingleSourceMaskImpl(ArrayRef<int> Mask, int NumOpElts) {
assert(!Mask.empty() && "Shuffle mask must contain elements");
bool UsesLHS = false;
bool UsesRHS = false;
- for (int i = 0, NumElts = Mask.size(); i < NumElts; ++i) {
+ for (int i = 0, NumMaskElts = Mask.size(); i < NumMaskElts; ++i) {
if (Mask[i] == -1)
continue;
- assert(Mask[i] >= 0 && Mask[i] < (NumElts * 2) &&
+ assert(Mask[i] >= 0 && Mask[i] < (NumOpElts * 2) &&
"Out-of-bounds shuffle mask element");
- UsesLHS |= (Mask[i] < NumElts);
- UsesRHS |= (Mask[i] >= NumElts);
+ UsesLHS |= (Mask[i] < NumOpElts);
+ UsesRHS |= (Mask[i] >= NumOpElts);
if (UsesLHS && UsesRHS)
return false;
}
@@ -1678,18 +1678,30 @@ bool ShuffleVectorInst::isSingleSourceMask(ArrayRef<int> Mask) {
return true;
}
-bool ShuffleVectorInst::isIdentityMask(ArrayRef<int> Mask) {
- if (!isSingleSourceMask(Mask))
+bool ShuffleVectorInst::isSingleSourceMask(ArrayRef<int> Mask) {
+ // We don't have vector operand size information, so assume operands are the
+ // same size as the mask.
+ return isSingleSourceMaskImpl(Mask, Mask.size());
+}
+
+static bool isIdentityMaskImpl(ArrayRef<int> Mask, int NumOpElts) {
+ if (!isSingleSourceMaskImpl(Mask, NumOpElts))
return false;
- for (int i = 0, NumElts = Mask.size(); i < NumElts; ++i) {
+ for (int i = 0, NumMaskElts = Mask.size(); i < NumMaskElts; ++i) {
if (Mask[i] == -1)
continue;
- if (Mask[i] != i && Mask[i] != (NumElts + i))
+ if (Mask[i] != i && Mask[i] != (NumOpElts + i))
return false;
}
return true;
}
+bool ShuffleVectorInst::isIdentityMask(ArrayRef<int> Mask) {
+ // We don't have vector operand size information, so assume operands are the
+ // same size as the mask.
+ return isIdentityMaskImpl(Mask, Mask.size());
+}
+
bool ShuffleVectorInst::isReverseMask(ArrayRef<int> Mask) {
if (!isSingleSourceMask(Mask))
return false;
@@ -1761,6 +1773,33 @@ bool ShuffleVectorInst::isTransposeMask(ArrayRef<int> Mask) {
return true;
}
+bool ShuffleVectorInst::isIdentityWithPadding() const {
+ int NumOpElts = Op<0>()->getType()->getVectorNumElements();
+ int NumMaskElts = getType()->getVectorNumElements();
+ if (NumMaskElts <= NumOpElts)
+ return false;
+
+ // The first part of the mask must choose elements from exactly 1 source op.
+ ArrayRef<int> Mask = getShuffleMask();
+ if (!isIdentityMaskImpl(Mask, NumOpElts))
+ return false;
+
+ // All extending must be with undef elements.
+ for (int i = NumOpElts; i < NumMaskElts; ++i)
+ if (Mask[i] != -1)
+ return false;
+
+ return true;
+}
+
+bool ShuffleVectorInst::isIdentityWithExtract() const {
+ int NumOpElts = Op<0>()->getType()->getVectorNumElements();
+ int NumMaskElts = getType()->getVectorNumElements();
+ if (NumMaskElts >= NumOpElts)
+ return false;
+
+ return isIdentityMaskImpl(getShuffleMask(), NumOpElts);
+}
//===----------------------------------------------------------------------===//
// InsertValueInst Class