xref: /llvm-project/llvm/lib/Target/X86/X86ShuffleDecodeConstantPool.cpp (revision 253ca348b2ea5fbde89377dfbbedab100cef4e7a)
1 //===-- 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"
17 #include "llvm/CodeGen/MachineValueType.h"
18 #include "llvm/IR/Constants.h"
19 
20 //===----------------------------------------------------------------------===//
21 //  Vector Mask Decoding
22 //===----------------------------------------------------------------------===//
23 
24 namespace llvm {
25 
26 void DecodePSHUFBMask(const Constant *C, SmallVectorImpl<int> &ShuffleMask) {
27   Type *MaskTy = C->getType();
28   // It is not an error for the PSHUFB mask to not be a vector of i8 because the
29   // constant pool uniques constants by their bit representation.
30   // e.g. the following take up the same space in the constant pool:
31   //   i128 -170141183420855150465331762880109871104
32   //
33   //   <2 x i64> <i64 -9223372034707292160, i64 -9223372034707292160>
34   //
35   //   <4 x i32> <i32 -2147483648, i32 -2147483648,
36   //              i32 -2147483648, i32 -2147483648>
37 
38 #ifndef NDEBUG
39   unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
40   assert(MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512);
41 #endif
42 
43   if (!MaskTy->isVectorTy())
44     return;
45   int NumElts = MaskTy->getVectorNumElements();
46 
47   Type *EltTy = MaskTy->getVectorElementType();
48   if (!EltTy->isIntegerTy())
49     return;
50 
51   // The shuffle mask requires a byte vector - decode cases with
52   // wider elements as well.
53   unsigned BitWidth = cast<IntegerType>(EltTy)->getBitWidth();
54   if ((BitWidth % 8) != 0)
55     return;
56 
57   int Scale = BitWidth / 8;
58   int NumBytes = NumElts * Scale;
59   ShuffleMask.reserve(NumBytes);
60 
61   for (int i = 0; i != NumElts; ++i) {
62     Constant *COp = C->getAggregateElement(i);
63     if (!COp) {
64       ShuffleMask.clear();
65       return;
66     } else if (isa<UndefValue>(COp)) {
67       ShuffleMask.append(Scale, SM_SentinelUndef);
68       continue;
69     }
70 
71     APInt APElt = cast<ConstantInt>(COp)->getValue();
72     for (int j = 0; j != Scale; ++j) {
73       // For AVX vectors with 32 bytes the base of the shuffle is the 16-byte
74       // lane of the vector we're inside.
75       int Base = ((i * Scale) + j) & ~0xf;
76 
77       uint64_t Element = APElt.getLoBits(8).getZExtValue();
78       APElt = APElt.lshr(8);
79 
80       // If the high bit (7) of the byte is set, the element is zeroed.
81       if (Element & (1 << 7))
82         ShuffleMask.push_back(SM_SentinelZero);
83       else {
84         // Only the least significant 4 bits of the byte are used.
85         int Index = Base + (Element & 0xf);
86         ShuffleMask.push_back(Index);
87       }
88     }
89   }
90 
91   assert(NumBytes == (int)ShuffleMask.size() && "Unexpected shuffle mask size");
92 }
93 
94 void DecodeVPERMILPMask(const Constant *C, unsigned ElSize,
95                         SmallVectorImpl<int> &ShuffleMask) {
96   Type *MaskTy = C->getType();
97   // It is not an error for the PSHUFB mask to not be a vector of i8 because the
98   // constant pool uniques constants by their bit representation.
99   // e.g. the following take up the same space in the constant pool:
100   //   i128 -170141183420855150465331762880109871104
101   //
102   //   <2 x i64> <i64 -9223372034707292160, i64 -9223372034707292160>
103   //
104   //   <4 x i32> <i32 -2147483648, i32 -2147483648,
105   //              i32 -2147483648, i32 -2147483648>
106 
107   unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
108 
109   if (MaskTySize != 128 && MaskTySize != 256) // FIXME: Add support for AVX-512.
110     return;
111 
112   // Only support vector types.
113   if (!MaskTy->isVectorTy())
114     return;
115 
116   // Make sure its an integer type.
117   Type *VecEltTy = MaskTy->getVectorElementType();
118   if (!VecEltTy->isIntegerTy())
119     return;
120 
121   // Support any element type from byte up to element size.
122   // This is necessary primarily because 64-bit elements get split to 32-bit
123   // in the constant pool on 32-bit target.
124   unsigned EltTySize = VecEltTy->getIntegerBitWidth();
125   if (EltTySize < 8 || EltTySize > ElSize)
126     return;
127 
128   unsigned NumElements = MaskTySize / ElSize;
129   assert((NumElements == 2 || NumElements == 4 || NumElements == 8) &&
130          "Unexpected number of vector elements.");
131   ShuffleMask.reserve(NumElements);
132   unsigned NumElementsPerLane = 128 / ElSize;
133   unsigned Factor = ElSize / EltTySize;
134 
135   for (unsigned i = 0; i < NumElements; ++i) {
136     Constant *COp = C->getAggregateElement(i * Factor);
137     if (!COp) {
138       ShuffleMask.clear();
139       return;
140     } else if (isa<UndefValue>(COp)) {
141       ShuffleMask.push_back(SM_SentinelUndef);
142       continue;
143     }
144     int Index = i & ~(NumElementsPerLane - 1);
145     uint64_t Element = cast<ConstantInt>(COp)->getZExtValue();
146     if (ElSize == 64)
147       Index += (Element >> 1) & 0x1;
148     else
149       Index += Element & 0x3;
150     ShuffleMask.push_back(Index);
151   }
152 
153   // TODO: Handle funny-looking vectors too.
154 }
155 
156 void DecodeVPERMVMask(const Constant *C, MVT VT,
157                       SmallVectorImpl<int> &ShuffleMask) {
158   Type *MaskTy = C->getType();
159   if (MaskTy->isVectorTy()) {
160     unsigned NumElements = MaskTy->getVectorNumElements();
161     if (NumElements == VT.getVectorNumElements()) {
162       for (unsigned i = 0; i < NumElements; ++i) {
163         Constant *COp = C->getAggregateElement(i);
164         if (!COp || (!isa<UndefValue>(COp) && !isa<ConstantInt>(COp))) {
165           ShuffleMask.clear();
166           return;
167         }
168         if (isa<UndefValue>(COp))
169           ShuffleMask.push_back(SM_SentinelUndef);
170         else {
171           uint64_t Element = cast<ConstantInt>(COp)->getZExtValue();
172           Element &= (1 << NumElements) - 1;
173           ShuffleMask.push_back(Element);
174         }
175       }
176     }
177     return;
178   }
179   // Scalar value; just broadcast it
180   if (!isa<ConstantInt>(C))
181     return;
182   uint64_t Element = cast<ConstantInt>(C)->getZExtValue();
183   int NumElements = VT.getVectorNumElements();
184   Element &= (1 << NumElements) - 1;
185   for (int i = 0; i < NumElements; ++i)
186     ShuffleMask.push_back(Element);
187 }
188 
189 void DecodeVPERMV3Mask(const Constant *C, MVT VT,
190                        SmallVectorImpl<int> &ShuffleMask) {
191   Type *MaskTy = C->getType();
192   unsigned NumElements = MaskTy->getVectorNumElements();
193   if (NumElements == VT.getVectorNumElements()) {
194     unsigned EltMaskSize = Log2_64(NumElements * 2);
195     for (unsigned i = 0; i < NumElements; ++i) {
196       Constant *COp = C->getAggregateElement(i);
197       if (!COp) {
198         ShuffleMask.clear();
199         return;
200       }
201       if (isa<UndefValue>(COp))
202         ShuffleMask.push_back(SM_SentinelUndef);
203       else {
204         APInt Element = cast<ConstantInt>(COp)->getValue();
205         Element = Element.getLoBits(EltMaskSize);
206         ShuffleMask.push_back(Element.getZExtValue());
207       }
208     }
209   }
210 }
211 } // llvm namespace
212