blob: 9190b66367cdb8373cc498335f64010532c92ed4 [file] [log] [blame]
Craig Topper69653af2015-12-31 22:40:45 +00001//===-- 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"
Craig Topper53e5a38d2017-02-27 16:15:25 +000017#include "llvm/ADT/APInt.h"
Craig Topper69653af2015-12-31 22:40:45 +000018#include "llvm/CodeGen/MachineValueType.h"
19#include "llvm/IR/Constants.h"
20
21//===----------------------------------------------------------------------===//
22// Vector Mask Decoding
23//===----------------------------------------------------------------------===//
24
25namespace llvm {
26
Simon Pilgrim97a48202016-09-29 15:25:48 +000027static bool extractConstantMask(const Constant *C, unsigned MaskEltSizeInBits,
Craig Topper53e5a38d2017-02-27 16:15:25 +000028 APInt &UndefElts,
Simon Pilgrim97a48202016-09-29 15:25:48 +000029 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.
Craig Topper69653af2015-12-31 22:40:45 +000033 // 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>
Simon Pilgrim97a48202016-09-29 15:25:48 +000040 Type *CstTy = C->getType();
41 if (!CstTy->isVectorTy())
42 return false;
Craig Topper69653af2015-12-31 22:40:45 +000043
Simon Pilgrim97a48202016-09-29 15:25:48 +000044 Type *CstEltTy = CstTy->getVectorElementType();
45 if (!CstEltTy->isIntegerTy())
46 return false;
Craig Topper69653af2015-12-31 22:40:45 +000047
Simon Pilgrim97a48202016-09-29 15:25:48 +000048 unsigned CstSizeInBits = CstTy->getPrimitiveSizeInBits();
49 unsigned CstEltSizeInBits = CstTy->getScalarSizeInBits();
50 unsigned NumCstElts = CstTy->getVectorNumElements();
Craig Topper69653af2015-12-31 22:40:45 +000051
Simon Pilgrime86b7e22017-03-09 14:06:39 +000052 assert((CstSizeInBits % MaskEltSizeInBits) == 0 &&
53 "Unaligned shuffle mask size");
54
55 unsigned NumMaskElts = CstSizeInBits / MaskEltSizeInBits;
56 UndefElts = APInt(NumMaskElts, 0);
57 RawMask.resize(NumMaskElts, 0);
58
59 // Fast path - if the constants match the mask size then copy direct.
60 if (MaskEltSizeInBits == CstEltSizeInBits) {
61 assert(NumCstElts == NumMaskElts && "Unaligned shuffle mask size");
62 for (unsigned i = 0; i != NumMaskElts; ++i) {
63 Constant *COp = C->getAggregateElement(i);
64 if (!COp || (!isa<UndefValue>(COp) && !isa<ConstantInt>(COp)))
65 return false;
66
67 if (isa<UndefValue>(COp)) {
68 UndefElts.setBit(i);
69 RawMask[i] = 0;
70 continue;
71 }
72
73 auto *Elt = cast<ConstantInt>(COp);
74 RawMask[i] = Elt->getValue().getZExtValue();
75 }
76 return true;
77 }
78
Simon Pilgrim97a48202016-09-29 15:25:48 +000079 // Extract all the undef/constant element data and pack into single bitsets.
80 APInt UndefBits(CstSizeInBits, 0);
81 APInt MaskBits(CstSizeInBits, 0);
82 for (unsigned i = 0; i != NumCstElts; ++i) {
Simon Pilgrim05e48b92016-02-18 10:17:40 +000083 Constant *COp = C->getAggregateElement(i);
Simon Pilgrim97a48202016-09-29 15:25:48 +000084 if (!COp || (!isa<UndefValue>(COp) && !isa<ConstantInt>(COp)))
85 return false;
86
Simon Pilgrim3a895c42017-02-22 15:04:55 +000087 unsigned BitOffset = i * CstEltSizeInBits;
88
Simon Pilgrim97a48202016-09-29 15:25:48 +000089 if (isa<UndefValue>(COp)) {
Simon Pilgrimaed35222017-02-24 10:15:29 +000090 UndefBits.setBits(BitOffset, BitOffset + CstEltSizeInBits);
Simon Pilgrim05e48b92016-02-18 10:17:40 +000091 continue;
92 }
93
Simon Pilgrim3a895c42017-02-22 15:04:55 +000094 auto *Elt = cast<ConstantInt>(COp);
95 MaskBits |= Elt->getValue().zextOrTrunc(CstSizeInBits).shl(BitOffset);
Craig Topper69653af2015-12-31 22:40:45 +000096 }
Simon Pilgrim05e48b92016-02-18 10:17:40 +000097
Simon Pilgrim97a48202016-09-29 15:25:48 +000098 // Now extract the undef/constant bit data into the raw shuffle masks.
Simon Pilgrim97a48202016-09-29 15:25:48 +000099 for (unsigned i = 0; i != NumMaskElts; ++i) {
Simon Pilgrim0f5fb5f2017-02-25 20:01:58 +0000100 unsigned BitOffset = i * MaskEltSizeInBits;
101 APInt EltUndef = UndefBits.extractBits(MaskEltSizeInBits, BitOffset);
Simon Pilgrim97a48202016-09-29 15:25:48 +0000102
103 // Only treat the element as UNDEF if all bits are UNDEF, otherwise
104 // treat it as zero.
Simon Pilgrim96ef0c12016-10-23 15:09:44 +0000105 if (EltUndef.isAllOnesValue()) {
Craig Topper53e5a38d2017-02-27 16:15:25 +0000106 UndefElts.setBit(i);
Simon Pilgrim97a48202016-09-29 15:25:48 +0000107 RawMask[i] = 0;
108 continue;
109 }
110
Simon Pilgrim0f5fb5f2017-02-25 20:01:58 +0000111 APInt EltBits = MaskBits.extractBits(MaskEltSizeInBits, BitOffset);
Simon Pilgrim97a48202016-09-29 15:25:48 +0000112 RawMask[i] = EltBits.getZExtValue();
113 }
114
115 return true;
116}
117
118void DecodePSHUFBMask(const Constant *C, SmallVectorImpl<int> &ShuffleMask) {
119 Type *MaskTy = C->getType();
120 unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
Douglas Katzman3ace13a2016-09-29 17:26:12 +0000121 (void)MaskTySize;
Simon Pilgrim630dd6f2016-10-01 20:12:56 +0000122 assert((MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512) &&
123 "Unexpected vector size.");
Simon Pilgrim97a48202016-09-29 15:25:48 +0000124
125 // The shuffle mask requires a byte vector.
Craig Topper53e5a38d2017-02-27 16:15:25 +0000126 APInt UndefElts;
Craig Toppere1be95c2017-02-27 16:15:27 +0000127 SmallVector<uint64_t, 64> RawMask;
Simon Pilgrim97a48202016-09-29 15:25:48 +0000128 if (!extractConstantMask(C, 8, UndefElts, RawMask))
129 return;
130
131 unsigned NumElts = RawMask.size();
132 assert((NumElts == 16 || NumElts == 32 || NumElts == 64) &&
133 "Unexpected number of vector elements.");
134
135 for (unsigned i = 0; i != NumElts; ++i) {
136 if (UndefElts[i]) {
137 ShuffleMask.push_back(SM_SentinelUndef);
138 continue;
139 }
140
141 uint64_t Element = RawMask[i];
142 // If the high bit (7) of the byte is set, the element is zeroed.
143 if (Element & (1 << 7))
144 ShuffleMask.push_back(SM_SentinelZero);
145 else {
146 // For AVX vectors with 32 bytes the base of the shuffle is the 16-byte
147 // lane of the vector we're inside.
148 unsigned Base = i & ~0xf;
149
150 // Only the least significant 4 bits of the byte are used.
151 int Index = Base + (Element & 0xf);
152 ShuffleMask.push_back(Index);
153 }
154 }
Craig Topper69653af2015-12-31 22:40:45 +0000155}
156
157void DecodeVPERMILPMask(const Constant *C, unsigned ElSize,
158 SmallVectorImpl<int> &ShuffleMask) {
159 Type *MaskTy = C->getType();
Simon Pilgrim48d83402016-07-13 15:10:43 +0000160 unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
Douglas Katzman3ace13a2016-09-29 17:26:12 +0000161 (void)MaskTySize;
Simon Pilgrim630dd6f2016-10-01 20:12:56 +0000162 assert((MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512) &&
163 "Unexpected vector size.");
164 assert((ElSize == 32 || ElSize == 64) && "Unexpected vector element size.");
Simon Pilgrim97a48202016-09-29 15:25:48 +0000165
166 // The shuffle mask requires elements the same size as the target.
Craig Topper53e5a38d2017-02-27 16:15:25 +0000167 APInt UndefElts;
Craig Toppere1be95c2017-02-27 16:15:27 +0000168 SmallVector<uint64_t, 16> RawMask;
Simon Pilgrim97a48202016-09-29 15:25:48 +0000169 if (!extractConstantMask(C, ElSize, UndefElts, RawMask))
Craig Topper69653af2015-12-31 22:40:45 +0000170 return;
171
Simon Pilgrim97a48202016-09-29 15:25:48 +0000172 unsigned NumElts = RawMask.size();
173 unsigned NumEltsPerLane = 128 / ElSize;
174 assert((NumElts == 2 || NumElts == 4 || NumElts == 8 || NumElts == 16) &&
Craig Topper69653af2015-12-31 22:40:45 +0000175 "Unexpected number of vector elements.");
Craig Topper69653af2015-12-31 22:40:45 +0000176
Simon Pilgrim97a48202016-09-29 15:25:48 +0000177 for (unsigned i = 0; i != NumElts; ++i) {
178 if (UndefElts[i]) {
Craig Topper69653af2015-12-31 22:40:45 +0000179 ShuffleMask.push_back(SM_SentinelUndef);
180 continue;
181 }
Simon Pilgrim97a48202016-09-29 15:25:48 +0000182
183 int Index = i & ~(NumEltsPerLane - 1);
184 uint64_t Element = RawMask[i];
Craig Topper69653af2015-12-31 22:40:45 +0000185 if (ElSize == 64)
186 Index += (Element >> 1) & 0x1;
187 else
188 Index += Element & 0x3;
Simon Pilgrim97a48202016-09-29 15:25:48 +0000189
Craig Topper69653af2015-12-31 22:40:45 +0000190 ShuffleMask.push_back(Index);
191 }
Craig Topper69653af2015-12-31 22:40:45 +0000192}
193
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000194void DecodeVPERMIL2PMask(const Constant *C, unsigned M2Z, unsigned ElSize,
195 SmallVectorImpl<int> &ShuffleMask) {
196 Type *MaskTy = C->getType();
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000197 unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
Douglas Katzman3ace13a2016-09-29 17:26:12 +0000198 (void)MaskTySize;
Simon Pilgrim630dd6f2016-10-01 20:12:56 +0000199 assert((MaskTySize == 128 || MaskTySize == 256) && "Unexpected vector size.");
Simon Pilgrim97a48202016-09-29 15:25:48 +0000200
201 // The shuffle mask requires elements the same size as the target.
Craig Topper53e5a38d2017-02-27 16:15:25 +0000202 APInt UndefElts;
Simon Pilgrim97a48202016-09-29 15:25:48 +0000203 SmallVector<uint64_t, 8> RawMask;
204 if (!extractConstantMask(C, ElSize, UndefElts, RawMask))
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000205 return;
206
Simon Pilgrim97a48202016-09-29 15:25:48 +0000207 unsigned NumElts = RawMask.size();
208 unsigned NumEltsPerLane = 128 / ElSize;
209 assert((NumElts == 2 || NumElts == 4 || NumElts == 8) &&
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000210 "Unexpected number of vector elements.");
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000211
Simon Pilgrim97a48202016-09-29 15:25:48 +0000212 for (unsigned i = 0; i != NumElts; ++i) {
213 if (UndefElts[i]) {
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000214 ShuffleMask.push_back(SM_SentinelUndef);
215 continue;
216 }
217
218 // VPERMIL2 Operation.
219 // Bits[3] - Match Bit.
220 // Bits[2:1] - (Per Lane) PD Shuffle Mask.
221 // Bits[2:0] - (Per Lane) PS Shuffle Mask.
Simon Pilgrim97a48202016-09-29 15:25:48 +0000222 uint64_t Selector = RawMask[i];
Chandler Carruth4c0e94d2016-06-11 09:13:00 +0000223 unsigned MatchBit = (Selector >> 3) & 0x1;
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000224
225 // M2Z[0:1] MatchBit
226 // 0Xb X Source selected by Selector index.
227 // 10b 0 Source selected by Selector index.
228 // 10b 1 Zero.
229 // 11b 0 Zero.
230 // 11b 1 Source selected by Selector index.
Chandler Carruth306e2702016-06-11 08:02:01 +0000231 if ((M2Z & 0x2) != 0u && MatchBit != (M2Z & 0x1)) {
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000232 ShuffleMask.push_back(SM_SentinelZero);
233 continue;
234 }
235
Simon Pilgrim97a48202016-09-29 15:25:48 +0000236 int Index = i & ~(NumEltsPerLane - 1);
Simon Pilgrim163987a2016-06-05 14:33:43 +0000237 if (ElSize == 64)
238 Index += (Selector >> 1) & 0x1;
239 else
240 Index += Selector & 0x3;
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000241
242 int Src = (Selector >> 2) & 0x1;
Simon Pilgrim97a48202016-09-29 15:25:48 +0000243 Index += Src * NumElts;
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000244 ShuffleMask.push_back(Index);
245 }
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000246}
247
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000248void DecodeVPPERMMask(const Constant *C, SmallVectorImpl<int> &ShuffleMask) {
Simon Pilgrim630dd6f2016-10-01 20:12:56 +0000249 assert(C->getType()->getPrimitiveSizeInBits() == 128 &&
250 "Unexpected vector size.");
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000251
Simon Pilgrim97a48202016-09-29 15:25:48 +0000252 // The shuffle mask requires a byte vector.
Craig Topper53e5a38d2017-02-27 16:15:25 +0000253 APInt UndefElts;
Craig Toppere1be95c2017-02-27 16:15:27 +0000254 SmallVector<uint64_t, 16> RawMask;
Simon Pilgrim97a48202016-09-29 15:25:48 +0000255 if (!extractConstantMask(C, 8, UndefElts, RawMask))
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000256 return;
257
Simon Pilgrim97a48202016-09-29 15:25:48 +0000258 unsigned NumElts = RawMask.size();
259 assert(NumElts == 16 && "Unexpected number of vector elements.");
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000260
Simon Pilgrim97a48202016-09-29 15:25:48 +0000261 for (unsigned i = 0; i != NumElts; ++i) {
262 if (UndefElts[i]) {
263 ShuffleMask.push_back(SM_SentinelUndef);
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000264 continue;
265 }
266
267 // VPPERM Operation
268 // Bits[4:0] - Byte Index (0 - 31)
269 // Bits[7:5] - Permute Operation
270 //
271 // Permute Operation:
272 // 0 - Source byte (no logical operation).
273 // 1 - Invert source byte.
274 // 2 - Bit reverse of source byte.
275 // 3 - Bit reverse of inverted source byte.
276 // 4 - 00h (zero - fill).
277 // 5 - FFh (ones - fill).
278 // 6 - Most significant bit of source byte replicated in all bit positions.
Simon Pilgrim97a48202016-09-29 15:25:48 +0000279 // 7 - Invert most significant bit of source byte and replicate in all bit
280 // positions.
281 uint64_t Element = RawMask[i];
282 uint64_t Index = Element & 0x1F;
283 uint64_t PermuteOp = (Element >> 5) & 0x7;
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000284
Simon Pilgrim97a48202016-09-29 15:25:48 +0000285 if (PermuteOp == 4) {
286 ShuffleMask.push_back(SM_SentinelZero);
287 continue;
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000288 }
Simon Pilgrim97a48202016-09-29 15:25:48 +0000289 if (PermuteOp != 0) {
290 ShuffleMask.clear();
291 return;
292 }
293 ShuffleMask.push_back((int)Index);
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000294 }
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000295}
296
Craig Topper448358b2016-10-18 04:48:33 +0000297void DecodeVPERMVMask(const Constant *C, unsigned ElSize,
Craig Topper69653af2015-12-31 22:40:45 +0000298 SmallVectorImpl<int> &ShuffleMask) {
299 Type *MaskTy = C->getType();
Craig Topper448358b2016-10-18 04:48:33 +0000300 unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
301 (void)MaskTySize;
302 assert((MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512) &&
303 "Unexpected vector size.");
304 assert((ElSize == 8 || ElSize == 16 || ElSize == 32 || ElSize == 64) &&
305 "Unexpected vector element size.");
306
307 // The shuffle mask requires elements the same size as the target.
Craig Topper53e5a38d2017-02-27 16:15:25 +0000308 APInt UndefElts;
Craig Toppere1be95c2017-02-27 16:15:27 +0000309 SmallVector<uint64_t, 64> RawMask;
Craig Topper448358b2016-10-18 04:48:33 +0000310 if (!extractConstantMask(C, ElSize, UndefElts, RawMask))
311 return;
312
313 unsigned NumElts = RawMask.size();
314
315 for (unsigned i = 0; i != NumElts; ++i) {
316 if (UndefElts[i]) {
317 ShuffleMask.push_back(SM_SentinelUndef);
318 continue;
Craig Topper69653af2015-12-31 22:40:45 +0000319 }
Craig Topper448358b2016-10-18 04:48:33 +0000320 int Index = RawMask[i] & (NumElts - 1);
321 ShuffleMask.push_back(Index);
Craig Topper69653af2015-12-31 22:40:45 +0000322 }
Craig Topper69653af2015-12-31 22:40:45 +0000323}
324
Craig Topper7268bf92016-10-18 04:00:32 +0000325void DecodeVPERMV3Mask(const Constant *C, unsigned ElSize,
Craig Topper69653af2015-12-31 22:40:45 +0000326 SmallVectorImpl<int> &ShuffleMask) {
327 Type *MaskTy = C->getType();
Craig Topper7268bf92016-10-18 04:00:32 +0000328 unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
329 (void)MaskTySize;
330 assert((MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512) &&
331 "Unexpected vector size.");
332 assert((ElSize == 8 || ElSize == 16 || ElSize == 32 || ElSize == 64) &&
333 "Unexpected vector element size.");
334
335 // The shuffle mask requires elements the same size as the target.
Craig Topper53e5a38d2017-02-27 16:15:25 +0000336 APInt UndefElts;
Craig Toppere1be95c2017-02-27 16:15:27 +0000337 SmallVector<uint64_t, 64> RawMask;
Craig Topper7268bf92016-10-18 04:00:32 +0000338 if (!extractConstantMask(C, ElSize, UndefElts, RawMask))
339 return;
340
341 unsigned NumElts = RawMask.size();
342
343 for (unsigned i = 0; i != NumElts; ++i) {
344 if (UndefElts[i]) {
345 ShuffleMask.push_back(SM_SentinelUndef);
346 continue;
Craig Topper69653af2015-12-31 22:40:45 +0000347 }
Craig Topper7268bf92016-10-18 04:00:32 +0000348 int Index = RawMask[i] & (NumElts*2 - 1);
349 ShuffleMask.push_back(Index);
Craig Topper69653af2015-12-31 22:40:45 +0000350 }
351}
352} // llvm namespace