]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/X86/X86ShuffleDecodeConstantPool.cpp
MFV r314911: 7867 ARC space accounting leak
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / X86 / X86ShuffleDecodeConstantPool.cpp
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