blob: 2cebb76022ef88427f3b3198f2a3f62532e2734c [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 Pilgrimb02667c2017-03-10 13:44:32 +000094 MaskBits.insertBits(cast<ConstantInt>(COp)->getValue(), BitOffset);
Craig Topper69653af2015-12-31 22:40:45 +000095 }
Simon Pilgrim05e48b92016-02-18 10:17:40 +000096
Simon Pilgrim97a48202016-09-29 15:25:48 +000097 // Now extract the undef/constant bit data into the raw shuffle masks.
Simon Pilgrim97a48202016-09-29 15:25:48 +000098 for (unsigned i = 0; i != NumMaskElts; ++i) {
Simon Pilgrim0f5fb5f2017-02-25 20:01:58 +000099 unsigned BitOffset = i * MaskEltSizeInBits;
100 APInt EltUndef = UndefBits.extractBits(MaskEltSizeInBits, BitOffset);
Simon Pilgrim97a48202016-09-29 15:25:48 +0000101
102 // Only treat the element as UNDEF if all bits are UNDEF, otherwise
103 // treat it as zero.
Simon Pilgrim96ef0c12016-10-23 15:09:44 +0000104 if (EltUndef.isAllOnesValue()) {
Craig Topper53e5a38d2017-02-27 16:15:25 +0000105 UndefElts.setBit(i);
Simon Pilgrim97a48202016-09-29 15:25:48 +0000106 RawMask[i] = 0;
107 continue;
108 }
109
Simon Pilgrim0f5fb5f2017-02-25 20:01:58 +0000110 APInt EltBits = MaskBits.extractBits(MaskEltSizeInBits, BitOffset);
Simon Pilgrim97a48202016-09-29 15:25:48 +0000111 RawMask[i] = EltBits.getZExtValue();
112 }
113
114 return true;
115}
116
117void DecodePSHUFBMask(const Constant *C, SmallVectorImpl<int> &ShuffleMask) {
118 Type *MaskTy = C->getType();
119 unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
Douglas Katzman3ace13a2016-09-29 17:26:12 +0000120 (void)MaskTySize;
Simon Pilgrim630dd6f2016-10-01 20:12:56 +0000121 assert((MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512) &&
122 "Unexpected vector size.");
Simon Pilgrim97a48202016-09-29 15:25:48 +0000123
124 // The shuffle mask requires a byte vector.
Craig Topper53e5a38d2017-02-27 16:15:25 +0000125 APInt UndefElts;
Craig Toppere1be95c2017-02-27 16:15:27 +0000126 SmallVector<uint64_t, 64> RawMask;
Simon Pilgrim97a48202016-09-29 15:25:48 +0000127 if (!extractConstantMask(C, 8, UndefElts, RawMask))
128 return;
129
130 unsigned NumElts = RawMask.size();
131 assert((NumElts == 16 || NumElts == 32 || NumElts == 64) &&
132 "Unexpected number of vector elements.");
133
134 for (unsigned i = 0; i != NumElts; ++i) {
135 if (UndefElts[i]) {
136 ShuffleMask.push_back(SM_SentinelUndef);
137 continue;
138 }
139
140 uint64_t Element = RawMask[i];
141 // If the high bit (7) of the byte is set, the element is zeroed.
142 if (Element & (1 << 7))
143 ShuffleMask.push_back(SM_SentinelZero);
144 else {
145 // For AVX vectors with 32 bytes the base of the shuffle is the 16-byte
146 // lane of the vector we're inside.
147 unsigned Base = i & ~0xf;
148
149 // Only the least significant 4 bits of the byte are used.
150 int Index = Base + (Element & 0xf);
151 ShuffleMask.push_back(Index);
152 }
153 }
Craig Topper69653af2015-12-31 22:40:45 +0000154}
155
156void DecodeVPERMILPMask(const Constant *C, unsigned ElSize,
157 SmallVectorImpl<int> &ShuffleMask) {
158 Type *MaskTy = C->getType();
Simon Pilgrim48d83402016-07-13 15:10:43 +0000159 unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
Douglas Katzman3ace13a2016-09-29 17:26:12 +0000160 (void)MaskTySize;
Simon Pilgrim630dd6f2016-10-01 20:12:56 +0000161 assert((MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512) &&
162 "Unexpected vector size.");
163 assert((ElSize == 32 || ElSize == 64) && "Unexpected vector element size.");
Simon Pilgrim97a48202016-09-29 15:25:48 +0000164
165 // The shuffle mask requires elements the same size as the target.
Craig Topper53e5a38d2017-02-27 16:15:25 +0000166 APInt UndefElts;
Craig Toppere1be95c2017-02-27 16:15:27 +0000167 SmallVector<uint64_t, 16> RawMask;
Simon Pilgrim97a48202016-09-29 15:25:48 +0000168 if (!extractConstantMask(C, ElSize, UndefElts, RawMask))
Craig Topper69653af2015-12-31 22:40:45 +0000169 return;
170
Simon Pilgrim97a48202016-09-29 15:25:48 +0000171 unsigned NumElts = RawMask.size();
172 unsigned NumEltsPerLane = 128 / ElSize;
173 assert((NumElts == 2 || NumElts == 4 || NumElts == 8 || NumElts == 16) &&
Craig Topper69653af2015-12-31 22:40:45 +0000174 "Unexpected number of vector elements.");
Craig Topper69653af2015-12-31 22:40:45 +0000175
Simon Pilgrim97a48202016-09-29 15:25:48 +0000176 for (unsigned i = 0; i != NumElts; ++i) {
177 if (UndefElts[i]) {
Craig Topper69653af2015-12-31 22:40:45 +0000178 ShuffleMask.push_back(SM_SentinelUndef);
179 continue;
180 }
Simon Pilgrim97a48202016-09-29 15:25:48 +0000181
182 int Index = i & ~(NumEltsPerLane - 1);
183 uint64_t Element = RawMask[i];
Craig Topper69653af2015-12-31 22:40:45 +0000184 if (ElSize == 64)
185 Index += (Element >> 1) & 0x1;
186 else
187 Index += Element & 0x3;
Simon Pilgrim97a48202016-09-29 15:25:48 +0000188
Craig Topper69653af2015-12-31 22:40:45 +0000189 ShuffleMask.push_back(Index);
190 }
Craig Topper69653af2015-12-31 22:40:45 +0000191}
192
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000193void DecodeVPERMIL2PMask(const Constant *C, unsigned M2Z, unsigned ElSize,
194 SmallVectorImpl<int> &ShuffleMask) {
195 Type *MaskTy = C->getType();
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000196 unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
Douglas Katzman3ace13a2016-09-29 17:26:12 +0000197 (void)MaskTySize;
Simon Pilgrim630dd6f2016-10-01 20:12:56 +0000198 assert((MaskTySize == 128 || MaskTySize == 256) && "Unexpected vector size.");
Simon Pilgrim97a48202016-09-29 15:25:48 +0000199
200 // The shuffle mask requires elements the same size as the target.
Craig Topper53e5a38d2017-02-27 16:15:25 +0000201 APInt UndefElts;
Simon Pilgrim97a48202016-09-29 15:25:48 +0000202 SmallVector<uint64_t, 8> RawMask;
203 if (!extractConstantMask(C, ElSize, UndefElts, RawMask))
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000204 return;
205
Simon Pilgrim97a48202016-09-29 15:25:48 +0000206 unsigned NumElts = RawMask.size();
207 unsigned NumEltsPerLane = 128 / ElSize;
208 assert((NumElts == 2 || NumElts == 4 || NumElts == 8) &&
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000209 "Unexpected number of vector elements.");
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000210
Simon Pilgrim97a48202016-09-29 15:25:48 +0000211 for (unsigned i = 0; i != NumElts; ++i) {
212 if (UndefElts[i]) {
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000213 ShuffleMask.push_back(SM_SentinelUndef);
214 continue;
215 }
216
217 // VPERMIL2 Operation.
218 // Bits[3] - Match Bit.
219 // Bits[2:1] - (Per Lane) PD Shuffle Mask.
220 // Bits[2:0] - (Per Lane) PS Shuffle Mask.
Simon Pilgrim97a48202016-09-29 15:25:48 +0000221 uint64_t Selector = RawMask[i];
Chandler Carruth4c0e94d2016-06-11 09:13:00 +0000222 unsigned MatchBit = (Selector >> 3) & 0x1;
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000223
224 // M2Z[0:1] MatchBit
225 // 0Xb X Source selected by Selector index.
226 // 10b 0 Source selected by Selector index.
227 // 10b 1 Zero.
228 // 11b 0 Zero.
229 // 11b 1 Source selected by Selector index.
Chandler Carruth306e2702016-06-11 08:02:01 +0000230 if ((M2Z & 0x2) != 0u && MatchBit != (M2Z & 0x1)) {
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000231 ShuffleMask.push_back(SM_SentinelZero);
232 continue;
233 }
234
Simon Pilgrim97a48202016-09-29 15:25:48 +0000235 int Index = i & ~(NumEltsPerLane - 1);
Simon Pilgrim163987a2016-06-05 14:33:43 +0000236 if (ElSize == 64)
237 Index += (Selector >> 1) & 0x1;
238 else
239 Index += Selector & 0x3;
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000240
241 int Src = (Selector >> 2) & 0x1;
Simon Pilgrim97a48202016-09-29 15:25:48 +0000242 Index += Src * NumElts;
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000243 ShuffleMask.push_back(Index);
244 }
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000245}
246
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000247void DecodeVPPERMMask(const Constant *C, SmallVectorImpl<int> &ShuffleMask) {
Simon Pilgrim630dd6f2016-10-01 20:12:56 +0000248 assert(C->getType()->getPrimitiveSizeInBits() == 128 &&
249 "Unexpected vector size.");
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000250
Simon Pilgrim97a48202016-09-29 15:25:48 +0000251 // The shuffle mask requires a byte vector.
Craig Topper53e5a38d2017-02-27 16:15:25 +0000252 APInt UndefElts;
Craig Toppere1be95c2017-02-27 16:15:27 +0000253 SmallVector<uint64_t, 16> RawMask;
Simon Pilgrim97a48202016-09-29 15:25:48 +0000254 if (!extractConstantMask(C, 8, UndefElts, RawMask))
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000255 return;
256
Simon Pilgrim97a48202016-09-29 15:25:48 +0000257 unsigned NumElts = RawMask.size();
258 assert(NumElts == 16 && "Unexpected number of vector elements.");
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000259
Simon Pilgrim97a48202016-09-29 15:25:48 +0000260 for (unsigned i = 0; i != NumElts; ++i) {
261 if (UndefElts[i]) {
262 ShuffleMask.push_back(SM_SentinelUndef);
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000263 continue;
264 }
265
266 // VPPERM Operation
267 // Bits[4:0] - Byte Index (0 - 31)
268 // Bits[7:5] - Permute Operation
269 //
270 // Permute Operation:
271 // 0 - Source byte (no logical operation).
272 // 1 - Invert source byte.
273 // 2 - Bit reverse of source byte.
274 // 3 - Bit reverse of inverted source byte.
275 // 4 - 00h (zero - fill).
276 // 5 - FFh (ones - fill).
277 // 6 - Most significant bit of source byte replicated in all bit positions.
Simon Pilgrim97a48202016-09-29 15:25:48 +0000278 // 7 - Invert most significant bit of source byte and replicate in all bit
279 // positions.
280 uint64_t Element = RawMask[i];
281 uint64_t Index = Element & 0x1F;
282 uint64_t PermuteOp = (Element >> 5) & 0x7;
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000283
Simon Pilgrim97a48202016-09-29 15:25:48 +0000284 if (PermuteOp == 4) {
285 ShuffleMask.push_back(SM_SentinelZero);
286 continue;
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000287 }
Simon Pilgrim97a48202016-09-29 15:25:48 +0000288 if (PermuteOp != 0) {
289 ShuffleMask.clear();
290 return;
291 }
292 ShuffleMask.push_back((int)Index);
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000293 }
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000294}
295
Craig Topper448358b2016-10-18 04:48:33 +0000296void DecodeVPERMVMask(const Constant *C, unsigned ElSize,
Craig Topper69653af2015-12-31 22:40:45 +0000297 SmallVectorImpl<int> &ShuffleMask) {
298 Type *MaskTy = C->getType();
Craig Topper448358b2016-10-18 04:48:33 +0000299 unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
300 (void)MaskTySize;
301 assert((MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512) &&
302 "Unexpected vector size.");
303 assert((ElSize == 8 || ElSize == 16 || ElSize == 32 || ElSize == 64) &&
304 "Unexpected vector element size.");
305
306 // The shuffle mask requires elements the same size as the target.
Craig Topper53e5a38d2017-02-27 16:15:25 +0000307 APInt UndefElts;
Craig Toppere1be95c2017-02-27 16:15:27 +0000308 SmallVector<uint64_t, 64> RawMask;
Craig Topper448358b2016-10-18 04:48:33 +0000309 if (!extractConstantMask(C, ElSize, UndefElts, RawMask))
310 return;
311
312 unsigned NumElts = RawMask.size();
313
314 for (unsigned i = 0; i != NumElts; ++i) {
315 if (UndefElts[i]) {
316 ShuffleMask.push_back(SM_SentinelUndef);
317 continue;
Craig Topper69653af2015-12-31 22:40:45 +0000318 }
Craig Topper448358b2016-10-18 04:48:33 +0000319 int Index = RawMask[i] & (NumElts - 1);
320 ShuffleMask.push_back(Index);
Craig Topper69653af2015-12-31 22:40:45 +0000321 }
Craig Topper69653af2015-12-31 22:40:45 +0000322}
323
Craig Topper7268bf92016-10-18 04:00:32 +0000324void DecodeVPERMV3Mask(const Constant *C, unsigned ElSize,
Craig Topper69653af2015-12-31 22:40:45 +0000325 SmallVectorImpl<int> &ShuffleMask) {
326 Type *MaskTy = C->getType();
Craig Topper7268bf92016-10-18 04:00:32 +0000327 unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
328 (void)MaskTySize;
329 assert((MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512) &&
330 "Unexpected vector size.");
331 assert((ElSize == 8 || ElSize == 16 || ElSize == 32 || ElSize == 64) &&
332 "Unexpected vector element size.");
333
334 // The shuffle mask requires elements the same size as the target.
Craig Topper53e5a38d2017-02-27 16:15:25 +0000335 APInt UndefElts;
Craig Toppere1be95c2017-02-27 16:15:27 +0000336 SmallVector<uint64_t, 64> RawMask;
Craig Topper7268bf92016-10-18 04:00:32 +0000337 if (!extractConstantMask(C, ElSize, UndefElts, RawMask))
338 return;
339
340 unsigned NumElts = RawMask.size();
341
342 for (unsigned i = 0; i != NumElts; ++i) {
343 if (UndefElts[i]) {
344 ShuffleMask.push_back(SM_SentinelUndef);
345 continue;
Craig Topper69653af2015-12-31 22:40:45 +0000346 }
Craig Topper7268bf92016-10-18 04:00:32 +0000347 int Index = RawMask[i] & (NumElts*2 - 1);
348 ShuffleMask.push_back(Index);
Craig Topper69653af2015-12-31 22:40:45 +0000349 }
350}
351} // llvm namespace