xref: /llvm-project/llvm/lib/Target/X86/X86ShuffleDecodeConstantPool.cpp (revision 306e270b83a238eb66ed302b9530d1e48a41017a)
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/CodeGen/MachineValueType.h"
18 #include "llvm/IR/Constants.h"
19 
20 //===----------------------------------------------------------------------===//
21 //  Vector Mask Decoding
22 //===----------------------------------------------------------------------===//
23 
24 namespace llvm {
25 
26 void DecodePSHUFBMask(const Constant *C, SmallVectorImpl<int> &ShuffleMask) {
27   Type *MaskTy = C->getType();
28   // It is not an error for the PSHUFB mask to not be a vector of i8 because the
29   // constant pool uniques constants by their bit representation.
30   // e.g. the following take up the same space in the constant pool:
31   //   i128 -170141183420855150465331762880109871104
32   //
33   //   <2 x i64> <i64 -9223372034707292160, i64 -9223372034707292160>
34   //
35   //   <4 x i32> <i32 -2147483648, i32 -2147483648,
36   //              i32 -2147483648, i32 -2147483648>
37 
38 #ifndef NDEBUG
39   unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
40   assert(MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512);
41 #endif
42 
43   if (!MaskTy->isVectorTy())
44     return;
45   int NumElts = MaskTy->getVectorNumElements();
46 
47   Type *EltTy = MaskTy->getVectorElementType();
48   if (!EltTy->isIntegerTy())
49     return;
50 
51   // The shuffle mask requires a byte vector - decode cases with
52   // wider elements as well.
53   unsigned BitWidth = cast<IntegerType>(EltTy)->getBitWidth();
54   if ((BitWidth % 8) != 0)
55     return;
56 
57   int Scale = BitWidth / 8;
58   int NumBytes = NumElts * Scale;
59   ShuffleMask.reserve(NumBytes);
60 
61   for (int i = 0; i != NumElts; ++i) {
62     Constant *COp = C->getAggregateElement(i);
63     if (!COp) {
64       ShuffleMask.clear();
65       return;
66     } else if (isa<UndefValue>(COp)) {
67       ShuffleMask.append(Scale, SM_SentinelUndef);
68       continue;
69     }
70 
71     APInt APElt = cast<ConstantInt>(COp)->getValue();
72     for (int j = 0; j != Scale; ++j) {
73       // For AVX vectors with 32 bytes the base of the shuffle is the 16-byte
74       // lane of the vector we're inside.
75       int Base = ((i * Scale) + j) & ~0xf;
76 
77       uint64_t Element = APElt.getLoBits(8).getZExtValue();
78       APElt = APElt.lshr(8);
79 
80       // If the high bit (7) of the byte is set, the element is zeroed.
81       if (Element & (1 << 7))
82         ShuffleMask.push_back(SM_SentinelZero);
83       else {
84         // Only the least significant 4 bits of the byte are used.
85         int Index = Base + (Element & 0xf);
86         ShuffleMask.push_back(Index);
87       }
88     }
89   }
90 
91   assert(NumBytes == (int)ShuffleMask.size() && "Unexpected shuffle mask size");
92 }
93 
94 void DecodeVPERMILPMask(const Constant *C, unsigned ElSize,
95                         SmallVectorImpl<int> &ShuffleMask) {
96   Type *MaskTy = C->getType();
97   // It is not an error for the PSHUFB mask to not be a vector of i8 because the
98   // constant pool uniques constants by their bit representation.
99   // e.g. the following take up the same space in the constant pool:
100   //   i128 -170141183420855150465331762880109871104
101   //
102   //   <2 x i64> <i64 -9223372034707292160, i64 -9223372034707292160>
103   //
104   //   <4 x i32> <i32 -2147483648, i32 -2147483648,
105   //              i32 -2147483648, i32 -2147483648>
106 
107   unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
108 
109   if (MaskTySize != 128 && MaskTySize != 256) // FIXME: Add support for AVX-512.
110     return;
111 
112   // Only support vector types.
113   if (!MaskTy->isVectorTy())
114     return;
115 
116   // Make sure its an integer type.
117   Type *VecEltTy = MaskTy->getVectorElementType();
118   if (!VecEltTy->isIntegerTy())
119     return;
120 
121   // Support any element type from byte up to element size.
122   // This is necessary primarily because 64-bit elements get split to 32-bit
123   // in the constant pool on 32-bit target.
124   unsigned EltTySize = VecEltTy->getIntegerBitWidth();
125   if (EltTySize < 8 || EltTySize > ElSize)
126     return;
127 
128   unsigned NumElements = MaskTySize / ElSize;
129   assert((NumElements == 2 || NumElements == 4 || NumElements == 8) &&
130          "Unexpected number of vector elements.");
131   ShuffleMask.reserve(NumElements);
132   unsigned NumElementsPerLane = 128 / ElSize;
133   unsigned Factor = ElSize / EltTySize;
134 
135   for (unsigned i = 0; i < NumElements; ++i) {
136     Constant *COp = C->getAggregateElement(i * Factor);
137     if (!COp) {
138       ShuffleMask.clear();
139       return;
140     } else if (isa<UndefValue>(COp)) {
141       ShuffleMask.push_back(SM_SentinelUndef);
142       continue;
143     }
144     int Index = i & ~(NumElementsPerLane - 1);
145     uint64_t Element = cast<ConstantInt>(COp)->getZExtValue();
146     if (ElSize == 64)
147       Index += (Element >> 1) & 0x1;
148     else
149       Index += Element & 0x3;
150     ShuffleMask.push_back(Index);
151   }
152 
153   // TODO: Handle funny-looking vectors too.
154 }
155 
156 void DecodeVPERMIL2PMask(const Constant *C, unsigned M2Z, unsigned ElSize,
157                          SmallVectorImpl<int> &ShuffleMask) {
158   Type *MaskTy = C->getType();
159 
160   unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
161   if (MaskTySize != 128 && MaskTySize != 256)
162     return;
163 
164   // Only support vector types.
165   if (!MaskTy->isVectorTy())
166     return;
167 
168   // Make sure its an integer type.
169   Type *VecEltTy = MaskTy->getVectorElementType();
170   if (!VecEltTy->isIntegerTy())
171     return;
172 
173   // Support any element type from byte up to element size.
174   // This is necessary primarily because 64-bit elements get split to 32-bit
175   // in the constant pool on 32-bit target.
176   unsigned EltTySize = VecEltTy->getIntegerBitWidth();
177   if (EltTySize < 8 || EltTySize > ElSize)
178     return;
179 
180   unsigned NumElements = MaskTySize / ElSize;
181   assert((NumElements == 2 || NumElements == 4 || NumElements == 8) &&
182          "Unexpected number of vector elements.");
183   ShuffleMask.reserve(NumElements);
184   unsigned NumElementsPerLane = 128 / ElSize;
185   unsigned Factor = ElSize / EltTySize;
186 
187   for (unsigned i = 0; i < NumElements; ++i) {
188     Constant *COp = C->getAggregateElement(i * Factor);
189     if (!COp) {
190       ShuffleMask.clear();
191       return;
192     } else if (isa<UndefValue>(COp)) {
193       ShuffleMask.push_back(SM_SentinelUndef);
194       continue;
195     }
196 
197     // VPERMIL2 Operation.
198     // Bits[3] - Match Bit.
199     // Bits[2:1] - (Per Lane) PD Shuffle Mask.
200     // Bits[2:0] - (Per Lane) PS Shuffle Mask.
201     uint64_t Selector = cast<ConstantInt>(COp)->getZExtValue();
202     int MatchBit = (Selector >> 3) & 0x1;
203 
204     // M2Z[0:1]     MatchBit
205     //   0Xb           X        Source selected by Selector index.
206     //   10b           0        Source selected by Selector index.
207     //   10b           1        Zero.
208     //   11b           0        Zero.
209     //   11b           1        Source selected by Selector index.
210     if ((M2Z & 0x2) != 0u && MatchBit != (M2Z & 0x1)) {
211       ShuffleMask.push_back(SM_SentinelZero);
212       continue;
213     }
214 
215     int Index = i & ~(NumElementsPerLane - 1);
216     if (ElSize == 64)
217       Index += (Selector >> 1) & 0x1;
218     else
219       Index += Selector & 0x3;
220 
221     int Src = (Selector >> 2) & 0x1;
222     Index += Src * NumElements;
223     ShuffleMask.push_back(Index);
224   }
225 
226   // TODO: Handle funny-looking vectors too.
227 }
228 
229 void DecodeVPPERMMask(const Constant *C, SmallVectorImpl<int> &ShuffleMask) {
230   Type *MaskTy = C->getType();
231   assert(MaskTy->getPrimitiveSizeInBits() == 128);
232 
233   // Only support vector types.
234   if (!MaskTy->isVectorTy())
235     return;
236 
237   // Make sure its an integer type.
238   Type *VecEltTy = MaskTy->getVectorElementType();
239   if (!VecEltTy->isIntegerTy())
240     return;
241 
242   // The shuffle mask requires a byte vector - decode cases with
243   // wider elements as well.
244   unsigned BitWidth = cast<IntegerType>(VecEltTy)->getBitWidth();
245   if ((BitWidth % 8) != 0)
246     return;
247 
248   int NumElts = MaskTy->getVectorNumElements();
249   int Scale = BitWidth / 8;
250   int NumBytes = NumElts * Scale;
251   ShuffleMask.reserve(NumBytes);
252 
253   for (int i = 0; i != NumElts; ++i) {
254     Constant *COp = C->getAggregateElement(i);
255     if (!COp) {
256       ShuffleMask.clear();
257       return;
258     } else if (isa<UndefValue>(COp)) {
259       ShuffleMask.append(Scale, SM_SentinelUndef);
260       continue;
261     }
262 
263     // VPPERM Operation
264     // Bits[4:0] - Byte Index (0 - 31)
265     // Bits[7:5] - Permute Operation
266     //
267     // Permute Operation:
268     // 0 - Source byte (no logical operation).
269     // 1 - Invert source byte.
270     // 2 - Bit reverse of source byte.
271     // 3 - Bit reverse of inverted source byte.
272     // 4 - 00h (zero - fill).
273     // 5 - FFh (ones - fill).
274     // 6 - Most significant bit of source byte replicated in all bit positions.
275     // 7 - Invert most significant bit of source byte and replicate in all bit positions.
276     APInt MaskElt = cast<ConstantInt>(COp)->getValue();
277     for (int j = 0; j != Scale; ++j) {
278       APInt Index = MaskElt.getLoBits(5);
279       APInt PermuteOp = MaskElt.lshr(5).getLoBits(3);
280       MaskElt = MaskElt.lshr(8);
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.getZExtValue());
291     }
292   }
293 
294   assert(NumBytes == (int)ShuffleMask.size() && "Unexpected shuffle mask size");
295 }
296 
297 void DecodeVPERMVMask(const Constant *C, MVT VT,
298                       SmallVectorImpl<int> &ShuffleMask) {
299   Type *MaskTy = C->getType();
300   if (MaskTy->isVectorTy()) {
301     unsigned NumElements = MaskTy->getVectorNumElements();
302     if (NumElements == VT.getVectorNumElements()) {
303       for (unsigned i = 0; i < NumElements; ++i) {
304         Constant *COp = C->getAggregateElement(i);
305         if (!COp || (!isa<UndefValue>(COp) && !isa<ConstantInt>(COp))) {
306           ShuffleMask.clear();
307           return;
308         }
309         if (isa<UndefValue>(COp))
310           ShuffleMask.push_back(SM_SentinelUndef);
311         else {
312           uint64_t Element = cast<ConstantInt>(COp)->getZExtValue();
313           Element &= (1 << NumElements) - 1;
314           ShuffleMask.push_back(Element);
315         }
316       }
317     }
318     return;
319   }
320   // Scalar value; just broadcast it
321   if (!isa<ConstantInt>(C))
322     return;
323   uint64_t Element = cast<ConstantInt>(C)->getZExtValue();
324   int NumElements = VT.getVectorNumElements();
325   Element &= (1 << NumElements) - 1;
326   for (int i = 0; i < NumElements; ++i)
327     ShuffleMask.push_back(Element);
328 }
329 
330 void DecodeVPERMV3Mask(const Constant *C, MVT VT,
331                        SmallVectorImpl<int> &ShuffleMask) {
332   Type *MaskTy = C->getType();
333   unsigned NumElements = MaskTy->getVectorNumElements();
334   if (NumElements == VT.getVectorNumElements()) {
335     unsigned EltMaskSize = Log2_64(NumElements * 2);
336     for (unsigned i = 0; i < NumElements; ++i) {
337       Constant *COp = C->getAggregateElement(i);
338       if (!COp) {
339         ShuffleMask.clear();
340         return;
341       }
342       if (isa<UndefValue>(COp))
343         ShuffleMask.push_back(SM_SentinelUndef);
344       else {
345         APInt Element = cast<ConstantInt>(COp)->getValue();
346         Element = Element.getLoBits(EltMaskSize);
347         ShuffleMask.push_back(Element.getZExtValue());
348       }
349     }
350   }
351 }
352 } // llvm namespace
353