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