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//===----------------------------------------------------------------------===//
20//===----------------------------------------------------------------------===//
21// Vector Mask Decoding
22//===----------------------------------------------------------------------===//
29 // It is not an error for shuffle masks to not be a vector of
30 // MaskEltSizeInBits because the constant pool uniques constants by their
31 // bit representation.
32 // e.g. the following take up the same space in the constant pool:
33 // i128 -170141183420855150465331762880109871104
35 // <2 x i64> <i64 -9223372034707292160, i64 -9223372034707292160>
37 // <4 x i32> <i32 -2147483648, i32 -2147483648,
38 // i32 -2147483648, i32 -2147483648>
43 Type *CstEltTy = CstTy->getElementType();
48 unsigned CstEltSizeInBits = CstTy->getScalarSizeInBits();
49 unsigned NumCstElts = CstTy->getNumElements();
51 assert((CstSizeInBits % MaskEltSizeInBits) == 0 &&
52 "Unaligned shuffle mask size");
54 unsigned NumMaskElts = CstSizeInBits / MaskEltSizeInBits;
55 UndefElts =
APInt(NumMaskElts, 0);
56 RawMask.
resize(NumMaskElts, 0);
58 // Fast path - if the constants match the mask size then copy direct.
59 if (MaskEltSizeInBits == CstEltSizeInBits) {
60 assert(NumCstElts == NumMaskElts &&
"Unaligned shuffle mask size");
61 for (
unsigned i = 0; i != NumMaskElts; ++i) {
62 Constant *COp =
C->getAggregateElement(i);
73 RawMask[i] = Elt->getValue().getZExtValue();
78 // Extract all the undef/constant element data and pack into single bitsets.
79 APInt UndefBits(CstSizeInBits, 0);
80 APInt MaskBits(CstSizeInBits, 0);
81 for (
unsigned i = 0; i != NumCstElts; ++i) {
82 Constant *COp =
C->getAggregateElement(i);
86 unsigned BitOffset = i * CstEltSizeInBits;
89 UndefBits.
setBits(BitOffset, BitOffset + CstEltSizeInBits);
96 // Now extract the undef/constant bit data into the raw shuffle masks.
97 for (
unsigned i = 0; i != NumMaskElts; ++i) {
98 unsigned BitOffset = i * MaskEltSizeInBits;
101 // Only treat the element as UNDEF if all bits are UNDEF, otherwise
118 assert((Width == 128 || Width == 256 || Width == 512) &&
119 C->getType()->getPrimitiveSizeInBits() >= Width &&
120 "Unexpected vector size.");
122 // The shuffle mask requires a byte vector.
128 unsigned NumElts = Width / 8;
129 assert((NumElts == 16 || NumElts == 32 || NumElts == 64) &&
130 "Unexpected number of vector elements.");
132 for (
unsigned i = 0; i != NumElts; ++i) {
139 // If the high bit (7) of the byte is set, the element is zeroed.
140 if (Element & (1 << 7))
143 // For AVX vectors with 32 bytes the base of the shuffle is the 16-byte
144 // lane of the vector we're inside.
145 unsigned Base = i & ~0xf;
147 // Only the least significant 4 bits of the byte are used.
148 int Index =
Base + (Element & 0xf);
149 ShuffleMask.push_back(Index);
156 assert((Width == 128 || Width == 256 || Width == 512) &&
157 C->getType()->getPrimitiveSizeInBits() >= Width &&
158 "Unexpected vector size.");
159 assert((ElSize == 32 || ElSize == 64) &&
"Unexpected vector element size.");
161 // The shuffle mask requires elements the same size as the target.
167 unsigned NumElts = Width / ElSize;
168 unsigned NumEltsPerLane = 128 / ElSize;
169 assert((NumElts == 2 || NumElts == 4 || NumElts == 8 || NumElts == 16) &&
170 "Unexpected number of vector elements.");
172 for (
unsigned i = 0; i != NumElts; ++i) {
178 int Index = i & ~(NumEltsPerLane - 1);
181 Index += (Element >> 1) & 0x1;
183 Index += Element & 0x3;
185 ShuffleMask.push_back(Index);
191 Type *MaskTy =
C->getType();
194 assert((MaskTySize == 128 || MaskTySize == 256) && Width >= MaskTySize &&
195 "Unexpected vector size.");
197 // The shuffle mask requires elements the same size as the target.
203 unsigned NumElts = Width / ElSize;
204 unsigned NumEltsPerLane = 128 / ElSize;
205 assert((NumElts == 2 || NumElts == 4 || NumElts == 8) &&
206 "Unexpected number of vector elements.");
208 for (
unsigned i = 0; i != NumElts; ++i) {
214 // VPERMIL2 Operation.
215 // Bits[3] - Match Bit.
216 // Bits[2:1] - (Per Lane) PD Shuffle Mask.
217 // Bits[2:0] - (Per Lane) PS Shuffle Mask.
219 unsigned MatchBit = (Selector >> 3) & 0x1;
222 // 0Xb X Source selected by Selector index.
223 // 10b 0 Source selected by Selector index.
226 // 11b 1 Source selected by Selector index.
227 if ((M2Z & 0x2) != 0u && MatchBit != (M2Z & 0x1)) {
232 int Index = i & ~(NumEltsPerLane - 1);
234 Index += (Selector >> 1) & 0x1;
236 Index += Selector & 0x3;
238 int Src = (Selector >> 2) & 0x1;
239 Index += Src * NumElts;
240 ShuffleMask.push_back(Index);
246 Type *MaskTy =
C->getType();
249 assert(Width == 128 && Width >= MaskTySize &&
"Unexpected vector size.");
251 // The shuffle mask requires a byte vector.
257 unsigned NumElts = Width / 8;
258 assert(NumElts == 16 &&
"Unexpected number of vector elements.");
260 for (
unsigned i = 0; i != NumElts; ++i) {
267 // Bits[4:0] - Byte Index (0 - 31)
268 // Bits[7:5] - Permute Operation
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.
278 // 7 - Invert most significant bit of source byte and replicate in all bit
282 uint64_t PermuteOp = (Element >> 5) & 0x7;
284 if (PermuteOp == 4) {
288 if (PermuteOp != 0) {
292 ShuffleMask.push_back((
int)Index);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the SmallVector class.
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
LLVM_ABI void insertBits(const APInt &SubBits, unsigned bitPosition)
Insert the bits from a smaller APInt starting at bitPosition.
void setBits(unsigned loBit, unsigned hiBit)
Set the bits from loBit (inclusive) to hiBit (exclusive) to 1.
LLVM_ABI APInt extractBits(unsigned numBits, unsigned bitPosition) const
Return an APInt with the extracted bits [bitPosition,bitPosition+numBits).
This is an important base class in LLVM.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
void DecodeVPERMILPMask(unsigned NumElts, unsigned ScalarBits, ArrayRef< uint64_t > RawMask, const APInt &UndefElts, SmallVectorImpl< int > &ShuffleMask)
Decode a VPERMILPD/VPERMILPS variable mask from a raw array of constants.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
void DecodeVPERMIL2PMask(unsigned NumElts, unsigned ScalarBits, unsigned M2Z, ArrayRef< uint64_t > RawMask, const APInt &UndefElts, SmallVectorImpl< int > &ShuffleMask)
Decode a VPERMIL2PD/VPERMIL2PS variable mask from a raw array of constants.
static bool extractConstantMask(const Constant *C, unsigned MaskEltSizeInBits, APInt &UndefElts, SmallVectorImpl< uint64_t > &RawMask)
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
void DecodeVPPERMMask(ArrayRef< uint64_t > RawMask, const APInt &UndefElts, SmallVectorImpl< int > &ShuffleMask)
Decode a VPPERM mask from a raw array of constants such as from BUILD_VECTOR.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
void DecodePSHUFBMask(ArrayRef< uint64_t > RawMask, const APInt &UndefElts, SmallVectorImpl< int > &ShuffleMask)
Decode a PSHUFB mask from a raw array of constants such as from BUILD_VECTOR.