blob: 294981608428298d47c1338acf20f2c8d9c245c4 [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"
Simon Pilgrim97a48202016-09-29 15:25:48 +000017#include "llvm/ADT/SmallBitVector.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,
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.
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 Pilgrim97a48202016-09-29 15:25:48 +000052 // 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) {
Simon Pilgrim05e48b92016-02-18 10:17:40 +000056 Constant *COp = C->getAggregateElement(i);
Simon Pilgrim97a48202016-09-29 15:25:48 +000057 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);
Simon Pilgrim05e48b92016-02-18 10:17:40 +000063 continue;
64 }
65
Simon Pilgrim97a48202016-09-29 15:25:48 +000066 APInt EltBits = cast<ConstantInt>(COp)->getValue();
67 EltBits = EltBits.zextOrTrunc(CstSizeInBits);
68 MaskBits |= EltBits.shl(i * CstEltSizeInBits);
Craig Topper69653af2015-12-31 22:40:45 +000069 }
Simon Pilgrim05e48b92016-02-18 10:17:40 +000070
Simon Pilgrim97a48202016-09-29 15:25:48 +000071 // Now extract the undef/constant bit data into the raw shuffle masks.
Simon Pilgrim630dd6f2016-10-01 20:12:56 +000072 assert((CstSizeInBits % MaskEltSizeInBits) == 0 &&
73 "Unaligned shuffle mask size");
Simon Pilgrim97a48202016-09-29 15:25:48 +000074
Simon Pilgrim630dd6f2016-10-01 20:12:56 +000075 unsigned NumMaskElts = CstSizeInBits / MaskEltSizeInBits;
Simon Pilgrim97a48202016-09-29 15:25:48 +000076 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.countPopulation() == MaskEltSizeInBits) {
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
99void DecodePSHUFBMask(const Constant *C, SmallVectorImpl<int> &ShuffleMask) {
100 Type *MaskTy = C->getType();
101 unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
Douglas Katzman3ace13a2016-09-29 17:26:12 +0000102 (void)MaskTySize;
Simon Pilgrim630dd6f2016-10-01 20:12:56 +0000103 assert((MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512) &&
104 "Unexpected vector size.");
Simon Pilgrim97a48202016-09-29 15:25:48 +0000105
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 }
Craig Topper69653af2015-12-31 22:40:45 +0000136}
137
138void DecodeVPERMILPMask(const Constant *C, unsigned ElSize,
139 SmallVectorImpl<int> &ShuffleMask) {
140 Type *MaskTy = C->getType();
Simon Pilgrim48d83402016-07-13 15:10:43 +0000141 unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
Douglas Katzman3ace13a2016-09-29 17:26:12 +0000142 (void)MaskTySize;
Simon Pilgrim630dd6f2016-10-01 20:12:56 +0000143 assert((MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512) &&
144 "Unexpected vector size.");
145 assert((ElSize == 32 || ElSize == 64) && "Unexpected vector element size.");
Simon Pilgrim97a48202016-09-29 15:25:48 +0000146
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))
Craig Topper69653af2015-12-31 22:40:45 +0000151 return;
152
Simon Pilgrim97a48202016-09-29 15:25:48 +0000153 unsigned NumElts = RawMask.size();
154 unsigned NumEltsPerLane = 128 / ElSize;
155 assert((NumElts == 2 || NumElts == 4 || NumElts == 8 || NumElts == 16) &&
Craig Topper69653af2015-12-31 22:40:45 +0000156 "Unexpected number of vector elements.");
Craig Topper69653af2015-12-31 22:40:45 +0000157
Simon Pilgrim97a48202016-09-29 15:25:48 +0000158 for (unsigned i = 0; i != NumElts; ++i) {
159 if (UndefElts[i]) {
Craig Topper69653af2015-12-31 22:40:45 +0000160 ShuffleMask.push_back(SM_SentinelUndef);
161 continue;
162 }
Simon Pilgrim97a48202016-09-29 15:25:48 +0000163
164 int Index = i & ~(NumEltsPerLane - 1);
165 uint64_t Element = RawMask[i];
Craig Topper69653af2015-12-31 22:40:45 +0000166 if (ElSize == 64)
167 Index += (Element >> 1) & 0x1;
168 else
169 Index += Element & 0x3;
Simon Pilgrim97a48202016-09-29 15:25:48 +0000170
Craig Topper69653af2015-12-31 22:40:45 +0000171 ShuffleMask.push_back(Index);
172 }
Craig Topper69653af2015-12-31 22:40:45 +0000173}
174
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000175void DecodeVPERMIL2PMask(const Constant *C, unsigned M2Z, unsigned ElSize,
176 SmallVectorImpl<int> &ShuffleMask) {
177 Type *MaskTy = C->getType();
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000178 unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
Douglas Katzman3ace13a2016-09-29 17:26:12 +0000179 (void)MaskTySize;
Simon Pilgrim630dd6f2016-10-01 20:12:56 +0000180 assert((MaskTySize == 128 || MaskTySize == 256) && "Unexpected vector size.");
Simon Pilgrim97a48202016-09-29 15:25:48 +0000181
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))
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000186 return;
187
Simon Pilgrim97a48202016-09-29 15:25:48 +0000188 unsigned NumElts = RawMask.size();
189 unsigned NumEltsPerLane = 128 / ElSize;
190 assert((NumElts == 2 || NumElts == 4 || NumElts == 8) &&
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000191 "Unexpected number of vector elements.");
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000192
Simon Pilgrim97a48202016-09-29 15:25:48 +0000193 for (unsigned i = 0; i != NumElts; ++i) {
194 if (UndefElts[i]) {
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000195 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.
Simon Pilgrim97a48202016-09-29 15:25:48 +0000203 uint64_t Selector = RawMask[i];
Chandler Carruth4c0e94d2016-06-11 09:13:00 +0000204 unsigned MatchBit = (Selector >> 3) & 0x1;
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000205
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.
Chandler Carruth306e2702016-06-11 08:02:01 +0000212 if ((M2Z & 0x2) != 0u && MatchBit != (M2Z & 0x1)) {
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000213 ShuffleMask.push_back(SM_SentinelZero);
214 continue;
215 }
216
Simon Pilgrim97a48202016-09-29 15:25:48 +0000217 int Index = i & ~(NumEltsPerLane - 1);
Simon Pilgrim163987a2016-06-05 14:33:43 +0000218 if (ElSize == 64)
219 Index += (Selector >> 1) & 0x1;
220 else
221 Index += Selector & 0x3;
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000222
223 int Src = (Selector >> 2) & 0x1;
Simon Pilgrim97a48202016-09-29 15:25:48 +0000224 Index += Src * NumElts;
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000225 ShuffleMask.push_back(Index);
226 }
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000227}
228
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000229void DecodeVPPERMMask(const Constant *C, SmallVectorImpl<int> &ShuffleMask) {
Simon Pilgrim630dd6f2016-10-01 20:12:56 +0000230 assert(C->getType()->getPrimitiveSizeInBits() == 128 &&
231 "Unexpected vector size.");
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000232
Simon Pilgrim97a48202016-09-29 15:25:48 +0000233 // The shuffle mask requires a byte vector.
234 SmallBitVector UndefElts;
235 SmallVector<uint64_t, 32> RawMask;
236 if (!extractConstantMask(C, 8, UndefElts, RawMask))
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000237 return;
238
Simon Pilgrim97a48202016-09-29 15:25:48 +0000239 unsigned NumElts = RawMask.size();
240 assert(NumElts == 16 && "Unexpected number of vector elements.");
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000241
Simon Pilgrim97a48202016-09-29 15:25:48 +0000242 for (unsigned i = 0; i != NumElts; ++i) {
243 if (UndefElts[i]) {
244 ShuffleMask.push_back(SM_SentinelUndef);
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000245 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.
Simon Pilgrim97a48202016-09-29 15:25:48 +0000260 // 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;
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000265
Simon Pilgrim97a48202016-09-29 15:25:48 +0000266 if (PermuteOp == 4) {
267 ShuffleMask.push_back(SM_SentinelZero);
268 continue;
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000269 }
Simon Pilgrim97a48202016-09-29 15:25:48 +0000270 if (PermuteOp != 0) {
271 ShuffleMask.clear();
272 return;
273 }
274 ShuffleMask.push_back((int)Index);
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000275 }
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000276}
277
Craig Topper448358b2016-10-18 04:48:33 +0000278void DecodeVPERMVMask(const Constant *C, unsigned ElSize,
Craig Topper69653af2015-12-31 22:40:45 +0000279 SmallVectorImpl<int> &ShuffleMask) {
280 Type *MaskTy = C->getType();
Craig Topper448358b2016-10-18 04:48:33 +0000281 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;
Craig Topper69653af2015-12-31 22:40:45 +0000300 }
Craig Topper448358b2016-10-18 04:48:33 +0000301 int Index = RawMask[i] & (NumElts - 1);
302 ShuffleMask.push_back(Index);
Craig Topper69653af2015-12-31 22:40:45 +0000303 }
Craig Topper69653af2015-12-31 22:40:45 +0000304}
305
Craig Topper7268bf92016-10-18 04:00:32 +0000306void DecodeVPERMV3Mask(const Constant *C, unsigned ElSize,
Craig Topper69653af2015-12-31 22:40:45 +0000307 SmallVectorImpl<int> &ShuffleMask) {
308 Type *MaskTy = C->getType();
Craig Topper7268bf92016-10-18 04:00:32 +0000309 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;
Craig Topper69653af2015-12-31 22:40:45 +0000328 }
Craig Topper7268bf92016-10-18 04:00:32 +0000329 int Index = RawMask[i] & (NumElts*2 - 1);
330 ShuffleMask.push_back(Index);
Craig Topper69653af2015-12-31 22:40:45 +0000331 }
332}
333} // llvm namespace