1 //===-- X86ShuffleDecodeConstantPool.cpp - X86 shuffle decode -------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // Define several functions to decode x86 specific shuffle semantics using
10 // constants from the constant pool.
12 //===----------------------------------------------------------------------===//
14 #include "Utils/X86ShuffleDecode.h"
15 #include "llvm/ADT/APInt.h"
16 #include "llvm/IR/Constants.h"
18 //===----------------------------------------------------------------------===//
19 // Vector Mask Decoding
20 //===----------------------------------------------------------------------===//
24 static bool extractConstantMask(const Constant
*C
, unsigned MaskEltSizeInBits
,
26 SmallVectorImpl
<uint64_t> &RawMask
) {
27 // It is not an error for shuffle masks to not be a vector of
28 // MaskEltSizeInBits because the constant pool uniques constants by their
29 // bit representation.
30 // e.g. the following take up the same space in the constant pool:
31 // i128 -170141183420855150465331762880109871104
33 // <2 x i64> <i64 -9223372034707292160, i64 -9223372034707292160>
35 // <4 x i32> <i32 -2147483648, i32 -2147483648,
36 // i32 -2147483648, i32 -2147483648>
37 Type
*CstTy
= C
->getType();
38 if (!CstTy
->isVectorTy())
41 Type
*CstEltTy
= CstTy
->getVectorElementType();
42 if (!CstEltTy
->isIntegerTy())
45 unsigned CstSizeInBits
= CstTy
->getPrimitiveSizeInBits();
46 unsigned CstEltSizeInBits
= CstTy
->getScalarSizeInBits();
47 unsigned NumCstElts
= CstTy
->getVectorNumElements();
49 assert((CstSizeInBits
% MaskEltSizeInBits
) == 0 &&
50 "Unaligned shuffle mask size");
52 unsigned NumMaskElts
= CstSizeInBits
/ MaskEltSizeInBits
;
53 UndefElts
= APInt(NumMaskElts
, 0);
54 RawMask
.resize(NumMaskElts
, 0);
56 // Fast path - if the constants match the mask size then copy direct.
57 if (MaskEltSizeInBits
== CstEltSizeInBits
) {
58 assert(NumCstElts
== NumMaskElts
&& "Unaligned shuffle mask size");
59 for (unsigned i
= 0; i
!= NumMaskElts
; ++i
) {
60 Constant
*COp
= C
->getAggregateElement(i
);
61 if (!COp
|| (!isa
<UndefValue
>(COp
) && !isa
<ConstantInt
>(COp
)))
64 if (isa
<UndefValue
>(COp
)) {
70 auto *Elt
= cast
<ConstantInt
>(COp
);
71 RawMask
[i
] = Elt
->getValue().getZExtValue();
76 // Extract all the undef/constant element data and pack into single bitsets.
77 APInt
UndefBits(CstSizeInBits
, 0);
78 APInt
MaskBits(CstSizeInBits
, 0);
79 for (unsigned i
= 0; i
!= NumCstElts
; ++i
) {
80 Constant
*COp
= C
->getAggregateElement(i
);
81 if (!COp
|| (!isa
<UndefValue
>(COp
) && !isa
<ConstantInt
>(COp
)))
84 unsigned BitOffset
= i
* CstEltSizeInBits
;
86 if (isa
<UndefValue
>(COp
)) {
87 UndefBits
.setBits(BitOffset
, BitOffset
+ CstEltSizeInBits
);
91 MaskBits
.insertBits(cast
<ConstantInt
>(COp
)->getValue(), BitOffset
);
94 // Now extract the undef/constant bit data into the raw shuffle masks.
95 for (unsigned i
= 0; i
!= NumMaskElts
; ++i
) {
96 unsigned BitOffset
= i
* MaskEltSizeInBits
;
97 APInt EltUndef
= UndefBits
.extractBits(MaskEltSizeInBits
, BitOffset
);
99 // Only treat the element as UNDEF if all bits are UNDEF, otherwise
101 if (EltUndef
.isAllOnesValue()) {
107 APInt EltBits
= MaskBits
.extractBits(MaskEltSizeInBits
, BitOffset
);
108 RawMask
[i
] = EltBits
.getZExtValue();
114 void DecodePSHUFBMask(const Constant
*C
, unsigned Width
,
115 SmallVectorImpl
<int> &ShuffleMask
) {
116 assert((Width
== 128 || Width
== 256 || Width
== 512) &&
117 C
->getType()->getPrimitiveSizeInBits() >= Width
&&
118 "Unexpected vector size.");
120 // The shuffle mask requires a byte vector.
122 SmallVector
<uint64_t, 64> RawMask
;
123 if (!extractConstantMask(C
, 8, UndefElts
, RawMask
))
126 unsigned NumElts
= Width
/ 8;
127 assert((NumElts
== 16 || NumElts
== 32 || NumElts
== 64) &&
128 "Unexpected number of vector elements.");
130 for (unsigned i
= 0; i
!= NumElts
; ++i
) {
132 ShuffleMask
.push_back(SM_SentinelUndef
);
136 uint64_t Element
= RawMask
[i
];
137 // If the high bit (7) of the byte is set, the element is zeroed.
138 if (Element
& (1 << 7))
139 ShuffleMask
.push_back(SM_SentinelZero
);
141 // For AVX vectors with 32 bytes the base of the shuffle is the 16-byte
142 // lane of the vector we're inside.
143 unsigned Base
= i
& ~0xf;
145 // Only the least significant 4 bits of the byte are used.
146 int Index
= Base
+ (Element
& 0xf);
147 ShuffleMask
.push_back(Index
);
152 void DecodeVPERMILPMask(const Constant
*C
, unsigned ElSize
, unsigned Width
,
153 SmallVectorImpl
<int> &ShuffleMask
) {
154 assert((Width
== 128 || Width
== 256 || Width
== 512) &&
155 C
->getType()->getPrimitiveSizeInBits() >= Width
&&
156 "Unexpected vector size.");
157 assert((ElSize
== 32 || ElSize
== 64) && "Unexpected vector element size.");
159 // The shuffle mask requires elements the same size as the target.
161 SmallVector
<uint64_t, 16> RawMask
;
162 if (!extractConstantMask(C
, ElSize
, UndefElts
, RawMask
))
165 unsigned NumElts
= Width
/ ElSize
;
166 unsigned NumEltsPerLane
= 128 / ElSize
;
167 assert((NumElts
== 2 || NumElts
== 4 || NumElts
== 8 || NumElts
== 16) &&
168 "Unexpected number of vector elements.");
170 for (unsigned i
= 0; i
!= NumElts
; ++i
) {
172 ShuffleMask
.push_back(SM_SentinelUndef
);
176 int Index
= i
& ~(NumEltsPerLane
- 1);
177 uint64_t Element
= RawMask
[i
];
179 Index
+= (Element
>> 1) & 0x1;
181 Index
+= Element
& 0x3;
183 ShuffleMask
.push_back(Index
);
187 void DecodeVPERMIL2PMask(const Constant
*C
, unsigned M2Z
, unsigned ElSize
,
189 SmallVectorImpl
<int> &ShuffleMask
) {
190 Type
*MaskTy
= C
->getType();
191 unsigned MaskTySize
= MaskTy
->getPrimitiveSizeInBits();
193 assert((MaskTySize
== 128 || MaskTySize
== 256) &&
194 Width
>= MaskTySize
&& "Unexpected vector size.");
196 // The shuffle mask requires elements the same size as the target.
198 SmallVector
<uint64_t, 8> RawMask
;
199 if (!extractConstantMask(C
, ElSize
, UndefElts
, RawMask
))
202 unsigned NumElts
= Width
/ ElSize
;
203 unsigned NumEltsPerLane
= 128 / ElSize
;
204 assert((NumElts
== 2 || NumElts
== 4 || NumElts
== 8) &&
205 "Unexpected number of vector elements.");
207 for (unsigned i
= 0; i
!= NumElts
; ++i
) {
209 ShuffleMask
.push_back(SM_SentinelUndef
);
213 // VPERMIL2 Operation.
214 // Bits[3] - Match Bit.
215 // Bits[2:1] - (Per Lane) PD Shuffle Mask.
216 // Bits[2:0] - (Per Lane) PS Shuffle Mask.
217 uint64_t Selector
= RawMask
[i
];
218 unsigned MatchBit
= (Selector
>> 3) & 0x1;
221 // 0Xb X Source selected by Selector index.
222 // 10b 0 Source selected by Selector index.
225 // 11b 1 Source selected by Selector index.
226 if ((M2Z
& 0x2) != 0u && MatchBit
!= (M2Z
& 0x1)) {
227 ShuffleMask
.push_back(SM_SentinelZero
);
231 int Index
= i
& ~(NumEltsPerLane
- 1);
233 Index
+= (Selector
>> 1) & 0x1;
235 Index
+= Selector
& 0x3;
237 int Src
= (Selector
>> 2) & 0x1;
238 Index
+= Src
* NumElts
;
239 ShuffleMask
.push_back(Index
);
243 void DecodeVPPERMMask(const Constant
*C
, unsigned Width
,
244 SmallVectorImpl
<int> &ShuffleMask
) {
245 Type
*MaskTy
= C
->getType();
246 unsigned MaskTySize
= MaskTy
->getPrimitiveSizeInBits();
248 assert(Width
== 128 && Width
>= MaskTySize
&& "Unexpected vector size.");
250 // The shuffle mask requires a byte vector.
252 SmallVector
<uint64_t, 16> RawMask
;
253 if (!extractConstantMask(C
, 8, UndefElts
, RawMask
))
256 unsigned NumElts
= Width
/ 8;
257 assert(NumElts
== 16 && "Unexpected number of vector elements.");
259 for (unsigned i
= 0; i
!= NumElts
; ++i
) {
261 ShuffleMask
.push_back(SM_SentinelUndef
);
266 // Bits[4:0] - Byte Index (0 - 31)
267 // Bits[7:5] - Permute Operation
269 // Permute Operation:
270 // 0 - Source byte (no logical operation).
271 // 1 - Invert source byte.
272 // 2 - Bit reverse of source byte.
273 // 3 - Bit reverse of inverted source byte.
274 // 4 - 00h (zero - fill).
275 // 5 - FFh (ones - fill).
276 // 6 - Most significant bit of source byte replicated in all bit positions.
277 // 7 - Invert most significant bit of source byte and replicate in all bit
279 uint64_t Element
= RawMask
[i
];
280 uint64_t Index
= Element
& 0x1F;
281 uint64_t PermuteOp
= (Element
>> 5) & 0x7;
283 if (PermuteOp
== 4) {
284 ShuffleMask
.push_back(SM_SentinelZero
);
287 if (PermuteOp
!= 0) {
291 ShuffleMask
.push_back((int)Index
);
295 void DecodeVPERMVMask(const Constant
*C
, unsigned ElSize
, unsigned Width
,
296 SmallVectorImpl
<int> &ShuffleMask
) {
297 assert((Width
== 128 || Width
== 256 || Width
== 512) &&
298 C
->getType()->getPrimitiveSizeInBits() >= Width
&&
299 "Unexpected vector size.");
300 assert((ElSize
== 8 || ElSize
== 16 || ElSize
== 32 || ElSize
== 64) &&
301 "Unexpected vector element size.");
303 // The shuffle mask requires elements the same size as the target.
305 SmallVector
<uint64_t, 64> RawMask
;
306 if (!extractConstantMask(C
, ElSize
, UndefElts
, RawMask
))
309 unsigned NumElts
= Width
/ ElSize
;
311 for (unsigned i
= 0; i
!= NumElts
; ++i
) {
313 ShuffleMask
.push_back(SM_SentinelUndef
);
316 int Index
= RawMask
[i
] & (NumElts
- 1);
317 ShuffleMask
.push_back(Index
);
321 void DecodeVPERMV3Mask(const Constant
*C
, unsigned ElSize
, unsigned Width
,
322 SmallVectorImpl
<int> &ShuffleMask
) {
323 assert((Width
== 128 || Width
== 256 || Width
== 512) &&
324 C
->getType()->getPrimitiveSizeInBits() >= Width
&&
325 "Unexpected vector size.");
326 assert((ElSize
== 8 || ElSize
== 16 || ElSize
== 32 || ElSize
== 64) &&
327 "Unexpected vector element size.");
329 // The shuffle mask requires elements the same size as the target.
331 SmallVector
<uint64_t, 64> RawMask
;
332 if (!extractConstantMask(C
, ElSize
, UndefElts
, RawMask
))
335 unsigned NumElts
= Width
/ ElSize
;
337 for (unsigned i
= 0; i
!= NumElts
; ++i
) {
339 ShuffleMask
.push_back(SM_SentinelUndef
);
342 int Index
= RawMask
[i
] & (NumElts
*2 - 1);
343 ShuffleMask
.push_back(Index
);