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