14d0b32cdSDimitry Andric //===-- X86ShuffleDecodeConstantPool.cpp - X86 shuffle decode -------------===//
24d0b32cdSDimitry Andric //
34d0b32cdSDimitry Andric //                     The LLVM Compiler Infrastructure
44d0b32cdSDimitry Andric //
54d0b32cdSDimitry Andric // This file is distributed under the University of Illinois Open Source
64d0b32cdSDimitry Andric // License. See LICENSE.TXT for details.
74d0b32cdSDimitry Andric //
84d0b32cdSDimitry Andric //===----------------------------------------------------------------------===//
94d0b32cdSDimitry Andric //
104d0b32cdSDimitry Andric // Define several functions to decode x86 specific shuffle semantics using
114d0b32cdSDimitry Andric // constants from the constant pool.
124d0b32cdSDimitry Andric //
134d0b32cdSDimitry Andric //===----------------------------------------------------------------------===//
144d0b32cdSDimitry Andric 
154d0b32cdSDimitry Andric #include "X86ShuffleDecodeConstantPool.h"
164d0b32cdSDimitry Andric #include "Utils/X86ShuffleDecode.h"
174d0b32cdSDimitry Andric #include "llvm/CodeGen/MachineValueType.h"
184d0b32cdSDimitry Andric #include "llvm/IR/Constants.h"
194d0b32cdSDimitry Andric 
204d0b32cdSDimitry Andric //===----------------------------------------------------------------------===//
214d0b32cdSDimitry Andric //  Vector Mask Decoding
224d0b32cdSDimitry Andric //===----------------------------------------------------------------------===//
234d0b32cdSDimitry Andric 
244d0b32cdSDimitry Andric namespace llvm {
254d0b32cdSDimitry Andric 
264d0b32cdSDimitry Andric void DecodePSHUFBMask(const Constant *C, SmallVectorImpl<int> &ShuffleMask) {
274d0b32cdSDimitry Andric   Type *MaskTy = C->getType();
284d0b32cdSDimitry Andric   // It is not an error for the PSHUFB mask to not be a vector of i8 because the
294d0b32cdSDimitry Andric   // constant pool uniques constants by their bit representation.
304d0b32cdSDimitry Andric   // e.g. the following take up the same space in the constant pool:
314d0b32cdSDimitry Andric   //   i128 -170141183420855150465331762880109871104
324d0b32cdSDimitry Andric   //
334d0b32cdSDimitry Andric   //   <2 x i64> <i64 -9223372034707292160, i64 -9223372034707292160>
344d0b32cdSDimitry Andric   //
354d0b32cdSDimitry Andric   //   <4 x i32> <i32 -2147483648, i32 -2147483648,
364d0b32cdSDimitry Andric   //              i32 -2147483648, i32 -2147483648>
374d0b32cdSDimitry Andric 
384d0b32cdSDimitry Andric #ifndef NDEBUG
394d0b32cdSDimitry Andric   unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
404d0b32cdSDimitry Andric   assert(MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512);
414d0b32cdSDimitry Andric #endif
424d0b32cdSDimitry Andric 
434d0b32cdSDimitry Andric   // This is a straightforward byte vector.
444d0b32cdSDimitry Andric   if (MaskTy->isVectorTy() && MaskTy->getVectorElementType()->isIntegerTy(8)) {
454d0b32cdSDimitry Andric     int NumElements = MaskTy->getVectorNumElements();
464d0b32cdSDimitry Andric     ShuffleMask.reserve(NumElements);
474d0b32cdSDimitry Andric 
484d0b32cdSDimitry Andric     for (int i = 0; i < NumElements; ++i) {
494d0b32cdSDimitry Andric       // For AVX vectors with 32 bytes the base of the shuffle is the 16-byte
504d0b32cdSDimitry Andric       // lane of the vector we're inside.
514d0b32cdSDimitry Andric       int Base = i & ~0xf;
524d0b32cdSDimitry Andric       Constant *COp = C->getAggregateElement(i);
534d0b32cdSDimitry Andric       if (!COp) {
544d0b32cdSDimitry Andric         ShuffleMask.clear();
554d0b32cdSDimitry Andric         return;
564d0b32cdSDimitry Andric       } else if (isa<UndefValue>(COp)) {
574d0b32cdSDimitry Andric         ShuffleMask.push_back(SM_SentinelUndef);
584d0b32cdSDimitry Andric         continue;
594d0b32cdSDimitry Andric       }
604d0b32cdSDimitry Andric       uint64_t Element = cast<ConstantInt>(COp)->getZExtValue();
614d0b32cdSDimitry Andric       // If the high bit (7) of the byte is set, the element is zeroed.
624d0b32cdSDimitry Andric       if (Element & (1 << 7))
634d0b32cdSDimitry Andric         ShuffleMask.push_back(SM_SentinelZero);
644d0b32cdSDimitry Andric       else {
654d0b32cdSDimitry Andric         // Only the least significant 4 bits of the byte are used.
664d0b32cdSDimitry Andric         int Index = Base + (Element & 0xf);
674d0b32cdSDimitry Andric         ShuffleMask.push_back(Index);
684d0b32cdSDimitry Andric       }
694d0b32cdSDimitry Andric     }
704d0b32cdSDimitry Andric   }
714d0b32cdSDimitry Andric   // TODO: Handle funny-looking vectors too.
724d0b32cdSDimitry Andric }
734d0b32cdSDimitry Andric 
744d0b32cdSDimitry Andric void DecodeVPERMILPMask(const Constant *C, unsigned ElSize,
754d0b32cdSDimitry Andric                         SmallVectorImpl<int> &ShuffleMask) {
764d0b32cdSDimitry Andric   Type *MaskTy = C->getType();
774d0b32cdSDimitry Andric   // It is not an error for the PSHUFB mask to not be a vector of i8 because the
784d0b32cdSDimitry Andric   // constant pool uniques constants by their bit representation.
794d0b32cdSDimitry Andric   // e.g. the following take up the same space in the constant pool:
804d0b32cdSDimitry Andric   //   i128 -170141183420855150465331762880109871104
814d0b32cdSDimitry Andric   //
824d0b32cdSDimitry Andric   //   <2 x i64> <i64 -9223372034707292160, i64 -9223372034707292160>
834d0b32cdSDimitry Andric   //
844d0b32cdSDimitry Andric   //   <4 x i32> <i32 -2147483648, i32 -2147483648,
854d0b32cdSDimitry Andric   //              i32 -2147483648, i32 -2147483648>
864d0b32cdSDimitry Andric 
874d0b32cdSDimitry Andric   unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
884d0b32cdSDimitry Andric 
894d0b32cdSDimitry Andric   if (MaskTySize != 128 && MaskTySize != 256) // FIXME: Add support for AVX-512.
904d0b32cdSDimitry Andric     return;
914d0b32cdSDimitry Andric 
924d0b32cdSDimitry Andric   // Only support vector types.
934d0b32cdSDimitry Andric   if (!MaskTy->isVectorTy())
944d0b32cdSDimitry Andric     return;
954d0b32cdSDimitry Andric 
964d0b32cdSDimitry Andric   // Make sure its an integer type.
974d0b32cdSDimitry Andric   Type *VecEltTy = MaskTy->getVectorElementType();
984d0b32cdSDimitry Andric   if (!VecEltTy->isIntegerTy())
994d0b32cdSDimitry Andric     return;
1004d0b32cdSDimitry Andric 
1014d0b32cdSDimitry Andric   // Support any element type from byte up to element size.
1024d0b32cdSDimitry Andric   // This is necesary primarily because 64-bit elements get split to 32-bit
1034d0b32cdSDimitry Andric   // in the constant pool on 32-bit target.
1044d0b32cdSDimitry Andric   unsigned EltTySize = VecEltTy->getIntegerBitWidth();
1054d0b32cdSDimitry Andric   if (EltTySize < 8 || EltTySize > ElSize)
1064d0b32cdSDimitry Andric     return;
1074d0b32cdSDimitry Andric 
1084d0b32cdSDimitry Andric   unsigned NumElements = MaskTySize / ElSize;
1094d0b32cdSDimitry Andric   assert((NumElements == 2 || NumElements == 4 || NumElements == 8) &&
1104d0b32cdSDimitry Andric          "Unexpected number of vector elements.");
1114d0b32cdSDimitry Andric   ShuffleMask.reserve(NumElements);
1124d0b32cdSDimitry Andric   unsigned NumElementsPerLane = 128 / ElSize;
1134d0b32cdSDimitry Andric   unsigned Factor = ElSize / EltTySize;
1144d0b32cdSDimitry Andric 
1154d0b32cdSDimitry Andric   for (unsigned i = 0; i < NumElements; ++i) {
1164d0b32cdSDimitry Andric     Constant *COp = C->getAggregateElement(i * Factor);
1174d0b32cdSDimitry Andric     if (!COp) {
1184d0b32cdSDimitry Andric       ShuffleMask.clear();
1194d0b32cdSDimitry Andric       return;
1204d0b32cdSDimitry Andric     } else if (isa<UndefValue>(COp)) {
1214d0b32cdSDimitry Andric       ShuffleMask.push_back(SM_SentinelUndef);
1224d0b32cdSDimitry Andric       continue;
1234d0b32cdSDimitry Andric     }
1244d0b32cdSDimitry Andric     int Index = i & ~(NumElementsPerLane - 1);
1254d0b32cdSDimitry Andric     uint64_t Element = cast<ConstantInt>(COp)->getZExtValue();
1264d0b32cdSDimitry Andric     if (ElSize == 64)
1274d0b32cdSDimitry Andric       Index += (Element >> 1) & 0x1;
1284d0b32cdSDimitry Andric     else
1294d0b32cdSDimitry Andric       Index += Element & 0x3;
1304d0b32cdSDimitry Andric     ShuffleMask.push_back(Index);
1314d0b32cdSDimitry Andric   }
1324d0b32cdSDimitry Andric 
1334d0b32cdSDimitry Andric   // TODO: Handle funny-looking vectors too.
1344d0b32cdSDimitry Andric }
1354d0b32cdSDimitry Andric 
1364d0b32cdSDimitry Andric void DecodeVPERMVMask(const Constant *C, MVT VT,
1374d0b32cdSDimitry Andric                       SmallVectorImpl<int> &ShuffleMask) {
1384d0b32cdSDimitry Andric   Type *MaskTy = C->getType();
1394d0b32cdSDimitry Andric   if (MaskTy->isVectorTy()) {
1404d0b32cdSDimitry Andric     unsigned NumElements = MaskTy->getVectorNumElements();
1414d0b32cdSDimitry Andric     if (NumElements == VT.getVectorNumElements()) {
1424d0b32cdSDimitry Andric       for (unsigned i = 0; i < NumElements; ++i) {
1434d0b32cdSDimitry Andric         Constant *COp = C->getAggregateElement(i);
1444d0b32cdSDimitry Andric         if (!COp || (!isa<UndefValue>(COp) && !isa<ConstantInt>(COp))) {
1454d0b32cdSDimitry Andric           ShuffleMask.clear();
1464d0b32cdSDimitry Andric           return;
1474d0b32cdSDimitry Andric         }
1484d0b32cdSDimitry Andric         if (isa<UndefValue>(COp))
1494d0b32cdSDimitry Andric           ShuffleMask.push_back(SM_SentinelUndef);
1504d0b32cdSDimitry Andric         else {
1514d0b32cdSDimitry Andric           uint64_t Element = cast<ConstantInt>(COp)->getZExtValue();
1524d0b32cdSDimitry Andric           Element &= (1 << NumElements) - 1;
1534d0b32cdSDimitry Andric           ShuffleMask.push_back(Element);
1544d0b32cdSDimitry Andric         }
1554d0b32cdSDimitry Andric       }
1564d0b32cdSDimitry Andric     }
1574d0b32cdSDimitry Andric     return;
1584d0b32cdSDimitry Andric   }
1594d0b32cdSDimitry Andric   // Scalar value; just broadcast it
1604d0b32cdSDimitry Andric   if (!isa<ConstantInt>(C))
1614d0b32cdSDimitry Andric     return;
1624d0b32cdSDimitry Andric   uint64_t Element = cast<ConstantInt>(C)->getZExtValue();
1634d0b32cdSDimitry Andric   int NumElements = VT.getVectorNumElements();
1644d0b32cdSDimitry Andric   Element &= (1 << NumElements) - 1;
1654d0b32cdSDimitry Andric   for (int i = 0; i < NumElements; ++i)
1664d0b32cdSDimitry Andric     ShuffleMask.push_back(Element);
1674d0b32cdSDimitry Andric }
1684d0b32cdSDimitry Andric 
1694d0b32cdSDimitry Andric void DecodeVPERMV3Mask(const Constant *C, MVT VT,
1704d0b32cdSDimitry Andric                        SmallVectorImpl<int> &ShuffleMask) {
1714d0b32cdSDimitry Andric   Type *MaskTy = C->getType();
1724d0b32cdSDimitry Andric   unsigned NumElements = MaskTy->getVectorNumElements();
1734d0b32cdSDimitry Andric   if (NumElements == VT.getVectorNumElements()) {
1744d0b32cdSDimitry Andric     for (unsigned i = 0; i < NumElements; ++i) {
1754d0b32cdSDimitry Andric       Constant *COp = C->getAggregateElement(i);
1764d0b32cdSDimitry Andric       if (!COp) {
1774d0b32cdSDimitry Andric         ShuffleMask.clear();
1784d0b32cdSDimitry Andric         return;
1794d0b32cdSDimitry Andric       }
1804d0b32cdSDimitry Andric       if (isa<UndefValue>(COp))
1814d0b32cdSDimitry Andric         ShuffleMask.push_back(SM_SentinelUndef);
1824d0b32cdSDimitry Andric       else {
1834d0b32cdSDimitry Andric         uint64_t Element = cast<ConstantInt>(COp)->getZExtValue();
1844d0b32cdSDimitry Andric         Element &= (1 << NumElements*2) - 1;
1854d0b32cdSDimitry Andric         ShuffleMask.push_back(Element);
1864d0b32cdSDimitry Andric       }
1874d0b32cdSDimitry Andric     }
1884d0b32cdSDimitry Andric   }
1894d0b32cdSDimitry Andric }
1904d0b32cdSDimitry Andric } // llvm namespace
191