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