blob: 4d278d4b05aefa5ea379d0e3d411994c0af8858d [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
Simon Pilgrim3a895c42017-02-22 15:04:55 +000060 unsigned BitOffset = i * CstEltSizeInBits;
61
Simon Pilgrim97a48202016-09-29 15:25:48 +000062 if (isa<UndefValue>(COp)) {
Simon Pilgrim3a895c42017-02-22 15:04:55 +000063 unsigned HiBits = BitOffset + CstEltSizeInBits;
64 UndefBits |= APInt::getBitsSet(CstSizeInBits, BitOffset, HiBits);
Simon Pilgrim05e48b92016-02-18 10:17:40 +000065 continue;
66 }
67
Simon Pilgrim3a895c42017-02-22 15:04:55 +000068 auto *Elt = cast<ConstantInt>(COp);
69 MaskBits |= Elt->getValue().zextOrTrunc(CstSizeInBits).shl(BitOffset);
Craig Topper69653af2015-12-31 22:40:45 +000070 }
Simon Pilgrim05e48b92016-02-18 10:17:40 +000071
Simon Pilgrim97a48202016-09-29 15:25:48 +000072 // Now extract the undef/constant bit data into the raw shuffle masks.
Simon Pilgrim630dd6f2016-10-01 20:12:56 +000073 assert((CstSizeInBits % MaskEltSizeInBits) == 0 &&
74 "Unaligned shuffle mask size");
Simon Pilgrim97a48202016-09-29 15:25:48 +000075
Simon Pilgrim630dd6f2016-10-01 20:12:56 +000076 unsigned NumMaskElts = CstSizeInBits / MaskEltSizeInBits;
Simon Pilgrim97a48202016-09-29 15:25:48 +000077 UndefElts = SmallBitVector(NumMaskElts, false);
78 RawMask.resize(NumMaskElts, 0);
79
80 for (unsigned i = 0; i != NumMaskElts; ++i) {
81 APInt EltUndef = UndefBits.lshr(i * MaskEltSizeInBits);
82 EltUndef = EltUndef.zextOrTrunc(MaskEltSizeInBits);
83
84 // Only treat the element as UNDEF if all bits are UNDEF, otherwise
85 // treat it as zero.
Simon Pilgrim96ef0c12016-10-23 15:09:44 +000086 if (EltUndef.isAllOnesValue()) {
Simon Pilgrim97a48202016-09-29 15:25:48 +000087 UndefElts[i] = true;
88 RawMask[i] = 0;
89 continue;
90 }
91
92 APInt EltBits = MaskBits.lshr(i * MaskEltSizeInBits);
93 EltBits = EltBits.zextOrTrunc(MaskEltSizeInBits);
94 RawMask[i] = EltBits.getZExtValue();
95 }
96
97 return true;
98}
99
100void DecodePSHUFBMask(const Constant *C, SmallVectorImpl<int> &ShuffleMask) {
101 Type *MaskTy = C->getType();
102 unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
Douglas Katzman3ace13a2016-09-29 17:26:12 +0000103 (void)MaskTySize;
Simon Pilgrim630dd6f2016-10-01 20:12:56 +0000104 assert((MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512) &&
105 "Unexpected vector size.");
Simon Pilgrim97a48202016-09-29 15:25:48 +0000106
107 // The shuffle mask requires a byte vector.
108 SmallBitVector UndefElts;
109 SmallVector<uint64_t, 32> RawMask;
110 if (!extractConstantMask(C, 8, UndefElts, RawMask))
111 return;
112
113 unsigned NumElts = RawMask.size();
114 assert((NumElts == 16 || NumElts == 32 || NumElts == 64) &&
115 "Unexpected number of vector elements.");
116
117 for (unsigned i = 0; i != NumElts; ++i) {
118 if (UndefElts[i]) {
119 ShuffleMask.push_back(SM_SentinelUndef);
120 continue;
121 }
122
123 uint64_t Element = RawMask[i];
124 // If the high bit (7) of the byte is set, the element is zeroed.
125 if (Element & (1 << 7))
126 ShuffleMask.push_back(SM_SentinelZero);
127 else {
128 // For AVX vectors with 32 bytes the base of the shuffle is the 16-byte
129 // lane of the vector we're inside.
130 unsigned Base = i & ~0xf;
131
132 // Only the least significant 4 bits of the byte are used.
133 int Index = Base + (Element & 0xf);
134 ShuffleMask.push_back(Index);
135 }
136 }
Craig Topper69653af2015-12-31 22:40:45 +0000137}
138
139void DecodeVPERMILPMask(const Constant *C, unsigned ElSize,
140 SmallVectorImpl<int> &ShuffleMask) {
141 Type *MaskTy = C->getType();
Simon Pilgrim48d83402016-07-13 15:10:43 +0000142 unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
Douglas Katzman3ace13a2016-09-29 17:26:12 +0000143 (void)MaskTySize;
Simon Pilgrim630dd6f2016-10-01 20:12:56 +0000144 assert((MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512) &&
145 "Unexpected vector size.");
146 assert((ElSize == 32 || ElSize == 64) && "Unexpected vector element size.");
Simon Pilgrim97a48202016-09-29 15:25:48 +0000147
148 // The shuffle mask requires elements the same size as the target.
149 SmallBitVector UndefElts;
150 SmallVector<uint64_t, 8> RawMask;
151 if (!extractConstantMask(C, ElSize, UndefElts, RawMask))
Craig Topper69653af2015-12-31 22:40:45 +0000152 return;
153
Simon Pilgrim97a48202016-09-29 15:25:48 +0000154 unsigned NumElts = RawMask.size();
155 unsigned NumEltsPerLane = 128 / ElSize;
156 assert((NumElts == 2 || NumElts == 4 || NumElts == 8 || NumElts == 16) &&
Craig Topper69653af2015-12-31 22:40:45 +0000157 "Unexpected number of vector elements.");
Craig Topper69653af2015-12-31 22:40:45 +0000158
Simon Pilgrim97a48202016-09-29 15:25:48 +0000159 for (unsigned i = 0; i != NumElts; ++i) {
160 if (UndefElts[i]) {
Craig Topper69653af2015-12-31 22:40:45 +0000161 ShuffleMask.push_back(SM_SentinelUndef);
162 continue;
163 }
Simon Pilgrim97a48202016-09-29 15:25:48 +0000164
165 int Index = i & ~(NumEltsPerLane - 1);
166 uint64_t Element = RawMask[i];
Craig Topper69653af2015-12-31 22:40:45 +0000167 if (ElSize == 64)
168 Index += (Element >> 1) & 0x1;
169 else
170 Index += Element & 0x3;
Simon Pilgrim97a48202016-09-29 15:25:48 +0000171
Craig Topper69653af2015-12-31 22:40:45 +0000172 ShuffleMask.push_back(Index);
173 }
Craig Topper69653af2015-12-31 22:40:45 +0000174}
175
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000176void DecodeVPERMIL2PMask(const Constant *C, unsigned M2Z, unsigned ElSize,
177 SmallVectorImpl<int> &ShuffleMask) {
178 Type *MaskTy = C->getType();
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000179 unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
Douglas Katzman3ace13a2016-09-29 17:26:12 +0000180 (void)MaskTySize;
Simon Pilgrim630dd6f2016-10-01 20:12:56 +0000181 assert((MaskTySize == 128 || MaskTySize == 256) && "Unexpected vector size.");
Simon Pilgrim97a48202016-09-29 15:25:48 +0000182
183 // The shuffle mask requires elements the same size as the target.
184 SmallBitVector UndefElts;
185 SmallVector<uint64_t, 8> RawMask;
186 if (!extractConstantMask(C, ElSize, UndefElts, RawMask))
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000187 return;
188
Simon Pilgrim97a48202016-09-29 15:25:48 +0000189 unsigned NumElts = RawMask.size();
190 unsigned NumEltsPerLane = 128 / ElSize;
191 assert((NumElts == 2 || NumElts == 4 || NumElts == 8) &&
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000192 "Unexpected number of vector elements.");
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000193
Simon Pilgrim97a48202016-09-29 15:25:48 +0000194 for (unsigned i = 0; i != NumElts; ++i) {
195 if (UndefElts[i]) {
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000196 ShuffleMask.push_back(SM_SentinelUndef);
197 continue;
198 }
199
200 // VPERMIL2 Operation.
201 // Bits[3] - Match Bit.
202 // Bits[2:1] - (Per Lane) PD Shuffle Mask.
203 // Bits[2:0] - (Per Lane) PS Shuffle Mask.
Simon Pilgrim97a48202016-09-29 15:25:48 +0000204 uint64_t Selector = RawMask[i];
Chandler Carruth4c0e94d2016-06-11 09:13:00 +0000205 unsigned MatchBit = (Selector >> 3) & 0x1;
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000206
207 // M2Z[0:1] MatchBit
208 // 0Xb X Source selected by Selector index.
209 // 10b 0 Source selected by Selector index.
210 // 10b 1 Zero.
211 // 11b 0 Zero.
212 // 11b 1 Source selected by Selector index.
Chandler Carruth306e2702016-06-11 08:02:01 +0000213 if ((M2Z & 0x2) != 0u && MatchBit != (M2Z & 0x1)) {
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000214 ShuffleMask.push_back(SM_SentinelZero);
215 continue;
216 }
217
Simon Pilgrim97a48202016-09-29 15:25:48 +0000218 int Index = i & ~(NumEltsPerLane - 1);
Simon Pilgrim163987a2016-06-05 14:33:43 +0000219 if (ElSize == 64)
220 Index += (Selector >> 1) & 0x1;
221 else
222 Index += Selector & 0x3;
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000223
224 int Src = (Selector >> 2) & 0x1;
Simon Pilgrim97a48202016-09-29 15:25:48 +0000225 Index += Src * NumElts;
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000226 ShuffleMask.push_back(Index);
227 }
Simon Pilgrim2ead8612016-06-04 21:44:28 +0000228}
229
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000230void DecodeVPPERMMask(const Constant *C, SmallVectorImpl<int> &ShuffleMask) {
Simon Pilgrim630dd6f2016-10-01 20:12:56 +0000231 assert(C->getType()->getPrimitiveSizeInBits() == 128 &&
232 "Unexpected vector size.");
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000233
Simon Pilgrim97a48202016-09-29 15:25:48 +0000234 // The shuffle mask requires a byte vector.
235 SmallBitVector UndefElts;
236 SmallVector<uint64_t, 32> RawMask;
237 if (!extractConstantMask(C, 8, UndefElts, RawMask))
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000238 return;
239
Simon Pilgrim97a48202016-09-29 15:25:48 +0000240 unsigned NumElts = RawMask.size();
241 assert(NumElts == 16 && "Unexpected number of vector elements.");
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000242
Simon Pilgrim97a48202016-09-29 15:25:48 +0000243 for (unsigned i = 0; i != NumElts; ++i) {
244 if (UndefElts[i]) {
245 ShuffleMask.push_back(SM_SentinelUndef);
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000246 continue;
247 }
248
249 // VPPERM Operation
250 // Bits[4:0] - Byte Index (0 - 31)
251 // Bits[7:5] - Permute Operation
252 //
253 // Permute Operation:
254 // 0 - Source byte (no logical operation).
255 // 1 - Invert source byte.
256 // 2 - Bit reverse of source byte.
257 // 3 - Bit reverse of inverted source byte.
258 // 4 - 00h (zero - fill).
259 // 5 - FFh (ones - fill).
260 // 6 - Most significant bit of source byte replicated in all bit positions.
Simon Pilgrim97a48202016-09-29 15:25:48 +0000261 // 7 - Invert most significant bit of source byte and replicate in all bit
262 // positions.
263 uint64_t Element = RawMask[i];
264 uint64_t Index = Element & 0x1F;
265 uint64_t PermuteOp = (Element >> 5) & 0x7;
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000266
Simon Pilgrim97a48202016-09-29 15:25:48 +0000267 if (PermuteOp == 4) {
268 ShuffleMask.push_back(SM_SentinelZero);
269 continue;
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000270 }
Simon Pilgrim97a48202016-09-29 15:25:48 +0000271 if (PermuteOp != 0) {
272 ShuffleMask.clear();
273 return;
274 }
275 ShuffleMask.push_back((int)Index);
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000276 }
Simon Pilgrim1cc57122016-04-09 14:51:26 +0000277}
278
Craig Topper448358b2016-10-18 04:48:33 +0000279void DecodeVPERMVMask(const Constant *C, unsigned ElSize,
Craig Topper69653af2015-12-31 22:40:45 +0000280 SmallVectorImpl<int> &ShuffleMask) {
281 Type *MaskTy = C->getType();
Craig Topper448358b2016-10-18 04:48:33 +0000282 unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
283 (void)MaskTySize;
284 assert((MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512) &&
285 "Unexpected vector size.");
286 assert((ElSize == 8 || ElSize == 16 || ElSize == 32 || ElSize == 64) &&
287 "Unexpected vector element size.");
288
289 // The shuffle mask requires elements the same size as the target.
290 SmallBitVector UndefElts;
291 SmallVector<uint64_t, 8> RawMask;
292 if (!extractConstantMask(C, ElSize, UndefElts, RawMask))
293 return;
294
295 unsigned NumElts = RawMask.size();
296
297 for (unsigned i = 0; i != NumElts; ++i) {
298 if (UndefElts[i]) {
299 ShuffleMask.push_back(SM_SentinelUndef);
300 continue;
Craig Topper69653af2015-12-31 22:40:45 +0000301 }
Craig Topper448358b2016-10-18 04:48:33 +0000302 int Index = RawMask[i] & (NumElts - 1);
303 ShuffleMask.push_back(Index);
Craig Topper69653af2015-12-31 22:40:45 +0000304 }
Craig Topper69653af2015-12-31 22:40:45 +0000305}
306
Craig Topper7268bf92016-10-18 04:00:32 +0000307void DecodeVPERMV3Mask(const Constant *C, unsigned ElSize,
Craig Topper69653af2015-12-31 22:40:45 +0000308 SmallVectorImpl<int> &ShuffleMask) {
309 Type *MaskTy = C->getType();
Craig Topper7268bf92016-10-18 04:00:32 +0000310 unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
311 (void)MaskTySize;
312 assert((MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512) &&
313 "Unexpected vector size.");
314 assert((ElSize == 8 || ElSize == 16 || ElSize == 32 || ElSize == 64) &&
315 "Unexpected vector element size.");
316
317 // The shuffle mask requires elements the same size as the target.
318 SmallBitVector UndefElts;
319 SmallVector<uint64_t, 8> RawMask;
320 if (!extractConstantMask(C, ElSize, UndefElts, RawMask))
321 return;
322
323 unsigned NumElts = RawMask.size();
324
325 for (unsigned i = 0; i != NumElts; ++i) {
326 if (UndefElts[i]) {
327 ShuffleMask.push_back(SM_SentinelUndef);
328 continue;
Craig Topper69653af2015-12-31 22:40:45 +0000329 }
Craig Topper7268bf92016-10-18 04:00:32 +0000330 int Index = RawMask[i] & (NumElts*2 - 1);
331 ShuffleMask.push_back(Index);
Craig Topper69653af2015-12-31 22:40:45 +0000332 }
333}
334} // llvm namespace