LLVM  4.0.0
X86ShuffleDecodeConstantPool.cpp
Go to the documentation of this file.
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 
16 #include "Utils/X86ShuffleDecode.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;
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;
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
void push_back(const T &Elt)
Definition: SmallVector.h:211
void DecodeVPERMILPMask(MVT VT, ArrayRef< uint64_t > RawMask, SmallVectorImpl< int > &ShuffleMask)
Decode a VPERMILPD/VPERMILPS variable mask from a raw array of constants.
uint64_t getZExtValue() const
Get zero extended value.
Definition: APInt.h:1309
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
size_t i
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Get a value with low bits set.
Definition: APInt.h:536
APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
Definition: APInt.cpp:999
static bool extractConstantMask(const Constant *C, unsigned MaskEltSizeInBits, SmallBitVector &UndefElts, SmallVectorImpl< uint64_t > &RawMask)
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Definition: APInt.cpp:1122
Type * getVectorElementType() const
Definition: Type.h:353
APInt shl(unsigned shiftAmt) const
Left-shift function.
Definition: APInt.h:850
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
void DecodeVPPERMMask(ArrayRef< uint64_t > RawMask, SmallVectorImpl< int > &ShuffleMask)
Decode a VPPERM mask from a raw array of constants such as from BUILD_VECTOR.
bool isVectorTy() const
True if this is an instance of VectorType.
Definition: Type.h:219
This is an important base class in LLVM.
Definition: Constant.h:42
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
Definition: Constants.cpp:265
void DecodeVPERMVMask(ArrayRef< uint64_t > RawMask, SmallVectorImpl< int > &ShuffleMask)
Decode a VPERM W/D/Q/PS/PD mask from a raw array of constants.
void DecodeVPERMIL2PMask(MVT VT, unsigned M2Z, ArrayRef< uint64_t > RawMask, SmallVectorImpl< int > &ShuffleMask)
Decode a VPERMIL2PD/VPERMIL2PS variable mask from a raw array of constants.
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type...
Definition: Type.cpp:123
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:230
void DecodeVPERMV3Mask(ArrayRef< uint64_t > RawMask, SmallVectorImpl< int > &ShuffleMask)
Decode a VPERMT2 W/D/Q/PS/PD mask from a raw array of constants.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
Class for arbitrary precision integers.
Definition: APInt.h:77
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:195
unsigned getVectorNumElements() const
Definition: DerivedTypes.h:438
bool isAllOnesValue() const
Determine if all bits are set.
Definition: APInt.h:342
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:135
void DecodePSHUFBMask(ArrayRef< uint64_t > RawMask, SmallVectorImpl< int > &ShuffleMask)
Decode a PSHUFB mask from a raw array of constants such as from BUILD_VECTOR.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
unsigned getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition: Type.cpp:108
void resize(size_type N)
Definition: SmallVector.h:352