summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/X86/X86ShuffleDecodeConstantPool.cpp
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@gmail.com>2016-10-18 04:00:32 +0000
committerCraig Topper <craig.topper@gmail.com>2016-10-18 04:00:32 +0000
commit7268bf99ab480b54bb52675d662c71fa521c0411 (patch)
tree38d60353601818923bff973b8374558bdc565927 /llvm/lib/Target/X86/X86ShuffleDecodeConstantPool.cpp
parent175a415e7807ee8c94614753f1349e6cafc9f79c (diff)
downloadbcm5719-llvm-7268bf99ab480b54bb52675d662c71fa521c0411.tar.gz
bcm5719-llvm-7268bf99ab480b54bb52675d662c71fa521c0411.zip
[AVX-512] Fix DecodeVPERMV3Mask to handle cases where the constant pool entry has a different type than the shuffle itself.
Summary: This is especially important for 32-bit targets with 64-bit shuffle elements.This is similar to how PSHUFB and VPERMIL handle the same problem. Reviewers: RKSimon Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D25666 llvm-svn: 284451
Diffstat (limited to 'llvm/lib/Target/X86/X86ShuffleDecodeConstantPool.cpp')
-rw-r--r--llvm/lib/Target/X86/X86ShuffleDecodeConstantPool.cpp39
1 files changed, 22 insertions, 17 deletions
diff --git a/llvm/lib/Target/X86/X86ShuffleDecodeConstantPool.cpp b/llvm/lib/Target/X86/X86ShuffleDecodeConstantPool.cpp
index f00c85eda1a..04b00d34d92 100644
--- a/llvm/lib/Target/X86/X86ShuffleDecodeConstantPool.cpp
+++ b/llvm/lib/Target/X86/X86ShuffleDecodeConstantPool.cpp
@@ -309,26 +309,31 @@ void DecodeVPERMVMask(const Constant *C, MVT VT,
ShuffleMask.push_back(Element);
}
-void DecodeVPERMV3Mask(const Constant *C, MVT VT,
+void DecodeVPERMV3Mask(const Constant *C, unsigned ElSize,
SmallVectorImpl<int> &ShuffleMask) {
Type *MaskTy = C->getType();
- unsigned NumElements = MaskTy->getVectorNumElements();
- if (NumElements == VT.getVectorNumElements()) {
- unsigned EltMaskSize = Log2_64(NumElements * 2);
- for (unsigned i = 0; i < NumElements; ++i) {
- Constant *COp = C->getAggregateElement(i);
- if (!COp) {
- ShuffleMask.clear();
- return;
- }
- if (isa<UndefValue>(COp))
- ShuffleMask.push_back(SM_SentinelUndef);
- else {
- APInt Element = cast<ConstantInt>(COp)->getValue();
- Element = Element.getLoBits(EltMaskSize);
- ShuffleMask.push_back(Element.getZExtValue());
- }
+ unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
+ (void)MaskTySize;
+ assert((MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512) &&
+ "Unexpected vector size.");
+ assert((ElSize == 8 || ElSize == 16 || ElSize == 32 || ElSize == 64) &&
+ "Unexpected vector element size.");
+
+ // The shuffle mask requires elements the same size as the target.
+ SmallBitVector UndefElts;
+ SmallVector<uint64_t, 8> RawMask;
+ if (!extractConstantMask(C, ElSize, UndefElts, RawMask))
+ return;
+
+ unsigned NumElts = RawMask.size();
+
+ for (unsigned i = 0; i != NumElts; ++i) {
+ if (UndefElts[i]) {
+ ShuffleMask.push_back(SM_SentinelUndef);
+ continue;
}
+ int Index = RawMask[i] & (NumElts*2 - 1);
+ ShuffleMask.push_back(Index);
}
}
} // llvm namespace
OpenPOWER on IntegriCloud