1 //===-- X86ShuffleDecodeConstantPool.cpp - X86 shuffle decode -------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Define several functions to decode x86 specific shuffle semantics using 11 // constants from the constant pool. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "X86ShuffleDecodeConstantPool.h" 16 #include "Utils/X86ShuffleDecode.h" 17 #include "llvm/ADT/SmallBitVector.h" 18 #include "llvm/CodeGen/MachineValueType.h" 19 #include "llvm/IR/Constants.h" 20 21 //===----------------------------------------------------------------------===// 22 // Vector Mask Decoding 23 //===----------------------------------------------------------------------===// 24 25 namespace llvm { 26 27 static bool extractConstantMask(const Constant *C, unsigned MaskEltSizeInBits, 28 SmallBitVector &UndefElts, 29 SmallVectorImpl<uint64_t> &RawMask) { 30 // It is not an error for shuffle masks to not be a vector of 31 // MaskEltSizeInBits because the constant pool uniques constants by their 32 // bit representation. 33 // e.g. the following take up the same space in the constant pool: 34 // i128 -170141183420855150465331762880109871104 35 // 36 // <2 x i64> <i64 -9223372034707292160, i64 -9223372034707292160> 37 // 38 // <4 x i32> <i32 -2147483648, i32 -2147483648, 39 // i32 -2147483648, i32 -2147483648> 40 Type *CstTy = C->getType(); 41 if (!CstTy->isVectorTy()) 42 return false; 43 44 Type *CstEltTy = CstTy->getVectorElementType(); 45 if (!CstEltTy->isIntegerTy()) 46 return false; 47 48 unsigned CstSizeInBits = CstTy->getPrimitiveSizeInBits(); 49 unsigned CstEltSizeInBits = CstTy->getScalarSizeInBits(); 50 unsigned NumCstElts = CstTy->getVectorNumElements(); 51 52 // Extract all the undef/constant element data and pack into single bitsets. 53 APInt UndefBits(CstSizeInBits, 0); 54 APInt MaskBits(CstSizeInBits, 0); 55 for (unsigned i = 0; i != NumCstElts; ++i) { 56 Constant *COp = C->getAggregateElement(i); 57 if (!COp || (!isa<UndefValue>(COp) && !isa<ConstantInt>(COp))) 58 return false; 59 60 if (isa<UndefValue>(COp)) { 61 APInt EltUndef = APInt::getLowBitsSet(CstSizeInBits, CstEltSizeInBits); 62 UndefBits |= EltUndef.shl(i * CstEltSizeInBits); 63 continue; 64 } 65 66 APInt EltBits = cast<ConstantInt>(COp)->getValue(); 67 EltBits = EltBits.zextOrTrunc(CstSizeInBits); 68 MaskBits |= EltBits.shl(i * CstEltSizeInBits); 69 } 70 71 // Now extract the undef/constant bit data into the raw shuffle masks. 72 assert((CstSizeInBits % MaskEltSizeInBits) == 0 && 73 "Unaligned shuffle mask size"); 74 75 unsigned NumMaskElts = CstSizeInBits / MaskEltSizeInBits; 76 UndefElts = SmallBitVector(NumMaskElts, false); 77 RawMask.resize(NumMaskElts, 0); 78 79 for (unsigned i = 0; i != NumMaskElts; ++i) { 80 APInt EltUndef = UndefBits.lshr(i * MaskEltSizeInBits); 81 EltUndef = EltUndef.zextOrTrunc(MaskEltSizeInBits); 82 83 // Only treat the element as UNDEF if all bits are UNDEF, otherwise 84 // treat it as zero. 85 if (EltUndef.isAllOnesValue()) { 86 UndefElts[i] = true; 87 RawMask[i] = 0; 88 continue; 89 } 90 91 APInt EltBits = MaskBits.lshr(i * MaskEltSizeInBits); 92 EltBits = EltBits.zextOrTrunc(MaskEltSizeInBits); 93 RawMask[i] = EltBits.getZExtValue(); 94 } 95 96 return true; 97 } 98 99 void DecodePSHUFBMask(const Constant *C, SmallVectorImpl<int> &ShuffleMask) { 100 Type *MaskTy = C->getType(); 101 unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits(); 102 (void)MaskTySize; 103 assert((MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512) && 104 "Unexpected vector size."); 105 106 // The shuffle mask requires a byte vector. 107 SmallBitVector UndefElts; 108 SmallVector<uint64_t, 32> RawMask; 109 if (!extractConstantMask(C, 8, UndefElts, RawMask)) 110 return; 111 112 unsigned NumElts = RawMask.size(); 113 assert((NumElts == 16 || NumElts == 32 || NumElts == 64) && 114 "Unexpected number of vector elements."); 115 116 for (unsigned i = 0; i != NumElts; ++i) { 117 if (UndefElts[i]) { 118 ShuffleMask.push_back(SM_SentinelUndef); 119 continue; 120 } 121 122 uint64_t Element = RawMask[i]; 123 // If the high bit (7) of the byte is set, the element is zeroed. 124 if (Element & (1 << 7)) 125 ShuffleMask.push_back(SM_SentinelZero); 126 else { 127 // For AVX vectors with 32 bytes the base of the shuffle is the 16-byte 128 // lane of the vector we're inside. 129 unsigned Base = i & ~0xf; 130 131 // Only the least significant 4 bits of the byte are used. 132 int Index = Base + (Element & 0xf); 133 ShuffleMask.push_back(Index); 134 } 135 } 136 } 137 138 void DecodeVPERMILPMask(const Constant *C, unsigned ElSize, 139 SmallVectorImpl<int> &ShuffleMask) { 140 Type *MaskTy = C->getType(); 141 unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits(); 142 (void)MaskTySize; 143 assert((MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512) && 144 "Unexpected vector size."); 145 assert((ElSize == 32 || ElSize == 64) && "Unexpected vector element size."); 146 147 // The shuffle mask requires elements the same size as the target. 148 SmallBitVector UndefElts; 149 SmallVector<uint64_t, 8> RawMask; 150 if (!extractConstantMask(C, ElSize, UndefElts, RawMask)) 151 return; 152 153 unsigned NumElts = RawMask.size(); 154 unsigned NumEltsPerLane = 128 / ElSize; 155 assert((NumElts == 2 || NumElts == 4 || NumElts == 8 || NumElts == 16) && 156 "Unexpected number of vector elements."); 157 158 for (unsigned i = 0; i != NumElts; ++i) { 159 if (UndefElts[i]) { 160 ShuffleMask.push_back(SM_SentinelUndef); 161 continue; 162 } 163 164 int Index = i & ~(NumEltsPerLane - 1); 165 uint64_t Element = RawMask[i]; 166 if (ElSize == 64) 167 Index += (Element >> 1) & 0x1; 168 else 169 Index += Element & 0x3; 170 171 ShuffleMask.push_back(Index); 172 } 173 } 174 175 void DecodeVPERMIL2PMask(const Constant *C, unsigned M2Z, unsigned ElSize, 176 SmallVectorImpl<int> &ShuffleMask) { 177 Type *MaskTy = C->getType(); 178 unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits(); 179 (void)MaskTySize; 180 assert((MaskTySize == 128 || MaskTySize == 256) && "Unexpected vector size."); 181 182 // The shuffle mask requires elements the same size as the target. 183 SmallBitVector UndefElts; 184 SmallVector<uint64_t, 8> RawMask; 185 if (!extractConstantMask(C, ElSize, UndefElts, RawMask)) 186 return; 187 188 unsigned NumElts = RawMask.size(); 189 unsigned NumEltsPerLane = 128 / ElSize; 190 assert((NumElts == 2 || NumElts == 4 || NumElts == 8) && 191 "Unexpected number of vector elements."); 192 193 for (unsigned i = 0; i != NumElts; ++i) { 194 if (UndefElts[i]) { 195 ShuffleMask.push_back(SM_SentinelUndef); 196 continue; 197 } 198 199 // VPERMIL2 Operation. 200 // Bits[3] - Match Bit. 201 // Bits[2:1] - (Per Lane) PD Shuffle Mask. 202 // Bits[2:0] - (Per Lane) PS Shuffle Mask. 203 uint64_t Selector = RawMask[i]; 204 unsigned MatchBit = (Selector >> 3) & 0x1; 205 206 // M2Z[0:1] MatchBit 207 // 0Xb X Source selected by Selector index. 208 // 10b 0 Source selected by Selector index. 209 // 10b 1 Zero. 210 // 11b 0 Zero. 211 // 11b 1 Source selected by Selector index. 212 if ((M2Z & 0x2) != 0u && MatchBit != (M2Z & 0x1)) { 213 ShuffleMask.push_back(SM_SentinelZero); 214 continue; 215 } 216 217 int Index = i & ~(NumEltsPerLane - 1); 218 if (ElSize == 64) 219 Index += (Selector >> 1) & 0x1; 220 else 221 Index += Selector & 0x3; 222 223 int Src = (Selector >> 2) & 0x1; 224 Index += Src * NumElts; 225 ShuffleMask.push_back(Index); 226 } 227 } 228 229 void DecodeVPPERMMask(const Constant *C, SmallVectorImpl<int> &ShuffleMask) { 230 assert(C->getType()->getPrimitiveSizeInBits() == 128 && 231 "Unexpected vector size."); 232 233 // The shuffle mask requires a byte vector. 234 SmallBitVector UndefElts; 235 SmallVector<uint64_t, 32> RawMask; 236 if (!extractConstantMask(C, 8, UndefElts, RawMask)) 237 return; 238 239 unsigned NumElts = RawMask.size(); 240 assert(NumElts == 16 && "Unexpected number of vector elements."); 241 242 for (unsigned i = 0; i != NumElts; ++i) { 243 if (UndefElts[i]) { 244 ShuffleMask.push_back(SM_SentinelUndef); 245 continue; 246 } 247 248 // VPPERM Operation 249 // Bits[4:0] - Byte Index (0 - 31) 250 // Bits[7:5] - Permute Operation 251 // 252 // Permute Operation: 253 // 0 - Source byte (no logical operation). 254 // 1 - Invert source byte. 255 // 2 - Bit reverse of source byte. 256 // 3 - Bit reverse of inverted source byte. 257 // 4 - 00h (zero - fill). 258 // 5 - FFh (ones - fill). 259 // 6 - Most significant bit of source byte replicated in all bit positions. 260 // 7 - Invert most significant bit of source byte and replicate in all bit 261 // positions. 262 uint64_t Element = RawMask[i]; 263 uint64_t Index = Element & 0x1F; 264 uint64_t PermuteOp = (Element >> 5) & 0x7; 265 266 if (PermuteOp == 4) { 267 ShuffleMask.push_back(SM_SentinelZero); 268 continue; 269 } 270 if (PermuteOp != 0) { 271 ShuffleMask.clear(); 272 return; 273 } 274 ShuffleMask.push_back((int)Index); 275 } 276 } 277 278 void DecodeVPERMVMask(const Constant *C, unsigned ElSize, 279 SmallVectorImpl<int> &ShuffleMask) { 280 Type *MaskTy = C->getType(); 281 unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits(); 282 (void)MaskTySize; 283 assert((MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512) && 284 "Unexpected vector size."); 285 assert((ElSize == 8 || ElSize == 16 || ElSize == 32 || ElSize == 64) && 286 "Unexpected vector element size."); 287 288 // The shuffle mask requires elements the same size as the target. 289 SmallBitVector UndefElts; 290 SmallVector<uint64_t, 8> RawMask; 291 if (!extractConstantMask(C, ElSize, UndefElts, RawMask)) 292 return; 293 294 unsigned NumElts = RawMask.size(); 295 296 for (unsigned i = 0; i != NumElts; ++i) { 297 if (UndefElts[i]) { 298 ShuffleMask.push_back(SM_SentinelUndef); 299 continue; 300 } 301 int Index = RawMask[i] & (NumElts - 1); 302 ShuffleMask.push_back(Index); 303 } 304 } 305 306 void DecodeVPERMV3Mask(const Constant *C, unsigned ElSize, 307 SmallVectorImpl<int> &ShuffleMask) { 308 Type *MaskTy = C->getType(); 309 unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits(); 310 (void)MaskTySize; 311 assert((MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512) && 312 "Unexpected vector size."); 313 assert((ElSize == 8 || ElSize == 16 || ElSize == 32 || ElSize == 64) && 314 "Unexpected vector element size."); 315 316 // The shuffle mask requires elements the same size as the target. 317 SmallBitVector UndefElts; 318 SmallVector<uint64_t, 8> RawMask; 319 if (!extractConstantMask(C, ElSize, UndefElts, RawMask)) 320 return; 321 322 unsigned NumElts = RawMask.size(); 323 324 for (unsigned i = 0; i != NumElts; ++i) { 325 if (UndefElts[i]) { 326 ShuffleMask.push_back(SM_SentinelUndef); 327 continue; 328 } 329 int Index = RawMask[i] & (NumElts*2 - 1); 330 ShuffleMask.push_back(Index); 331 } 332 } 333 } // llvm namespace 334