xref: /freebsd/contrib/llvm-project/llvm/lib/Target/X86/X86ShuffleDecodeConstantPool.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
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