llvm.org GIT mirror llvm / d2f4460
X86: Properly decode shuffle masks when the constant pool type is weird It's possible for the constant pool entry for the shuffle mask to come from a completely different operation. This occurs when Constants have the same bit pattern but have different types. Make DecodePSHUFBMask tolerant of types which, after a bitcast, are appropriately sized vector types. This fixes PR22188. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225597 91177308-0d34-0410-b5e6-96231b3b80d8 David Majnemer 5 years ago
5 changed file(s) with 91 addition(s) and 67 deletion(s). Raw diff Collapse all Expand all
1212 //===----------------------------------------------------------------------===//
1313
1414 #include "X86ShuffleDecode.h"
15 #include "llvm/Analysis/ConstantFolding.h"
1516 #include "llvm/IR/Constants.h"
17 #include "llvm/IR/DataLayout.h"
18 #include "llvm/IR/InstrTypes.h"
1619 #include "llvm/CodeGen/MachineValueType.h"
1720
1821 //===----------------------------------------------------------------------===//
252255 }
253256 }
254257
255 void DecodePSHUFBMask(const Constant *C, SmallVectorImpl &ShuffleMask) {
258 void DecodePSHUFBMask(const Constant *C, const DataLayout *TD,
259 SmallVectorImpl &ShuffleMask) {
256260 Type *MaskTy = C->getType();
257 assert(MaskTy->isVectorTy() && "Expected a vector constant mask!");
258 assert(MaskTy->getVectorElementType()->isIntegerTy(8) &&
259 "Expected i8 constant mask elements!");
261 // It is not an error for the PSHUFB mask to not be a vector of i8 because the
262 // constant pool uniques constants by their bit representation.
263 // e.g. the following take up the same space in the constant pool:
264 // i128 -170141183420855150465331762880109871104
265 //
266 // <2 x i64>
267 //
268 // <4 x i32>
269 // -2147483648>
270
271 unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
272
273 VectorType *DestTy = nullptr;
274 if (MaskTySize == 128)
275 DestTy = VectorType::get(Type::getInt8Ty(MaskTy->getContext()), 16);
276 else if (MaskTySize == 256)
277 DestTy = VectorType::get(Type::getInt8Ty(MaskTy->getContext()), 32);
278
279 // FIXME: Add support for AVX-512.
280 if (!DestTy)
281 return;
282
283 if (DestTy != MaskTy) {
284 if (!CastInst::castIsValid(Instruction::BitCast, const_cast(C),
285 DestTy))
286 return;
287
288 C = ConstantFoldInstOperands(Instruction::BitCast, DestTy,
289 const_cast(C), TD);
290 MaskTy = DestTy;
291 }
292
260293 int NumElements = MaskTy->getVectorNumElements();
261 // FIXME: Add support for AVX-512.
262 assert((NumElements == 16 || NumElements == 32) &&
263 "Only 128-bit and 256-bit vectors supported!");
264294 ShuffleMask.reserve(NumElements);
265295
266 if (auto *CDS = dyn_cast(C)) {
267 assert((unsigned)NumElements == CDS->getNumElements() &&
268 "Constant mask has a different number of elements!");
269
270 for (int i = 0; i < NumElements; ++i) {
271 // For AVX vectors with 32 bytes the base of the shuffle is the 16-byte
272 // lane of the vector we're inside.
273 int Base = i < 16 ? 0 : 16;
274 uint64_t Element = CDS->getElementAsInteger(i);
275 // If the high bit (7) of the byte is set, the element is zeroed.
276 if (Element & (1 << 7))
277 ShuffleMask.push_back(SM_SentinelZero);
278 else {
279 // Only the least significant 4 bits of the byte are used.
280 int Index = Base + (Element & 0xf);
281 ShuffleMask.push_back(Index);
282 }
283 }
284 } else if (auto *CV = dyn_cast(C)) {
285 assert((unsigned)NumElements == CV->getNumOperands() &&
286 "Constant mask has a different number of elements!");
287
288 for (int i = 0; i < NumElements; ++i) {
289 // For AVX vectors with 32 bytes the base of the shuffle is the 16-byte
290 // lane of the vector we're inside.
291 int Base = i < 16 ? 0 : 16;
292 Constant *COp = CV->getOperand(i);
293 if (isa(COp)) {
294 ShuffleMask.push_back(SM_SentinelUndef);
295 continue;
296 }
297 uint64_t Element = cast(COp)->getZExtValue();
298 // If the high bit (7) of the byte is set, the element is zeroed.
299 if (Element & (1 << 7))
300 ShuffleMask.push_back(SM_SentinelZero);
301 else {
302 // Only the least significant 4 bits of the byte are used.
303 int Index = Base + (Element & 0xf);
304 ShuffleMask.push_back(Index);
305 }
296 for (int i = 0; i < NumElements; ++i) {
297 // For AVX vectors with 32 bytes the base of the shuffle is the 16-byte
298 // lane of the vector we're inside.
299 int Base = i < 16 ? 0 : 16;
300 Constant *COp = C->getAggregateElement(i);
301 if (!COp) {
302 ShuffleMask.clear();
303 return;
304 } else if (isa(COp)) {
305 ShuffleMask.push_back(SM_SentinelUndef);
306 continue;
307 }
308 uint64_t Element = cast(COp)->getZExtValue();
309 // If the high bit (7) of the byte is set, the element is zeroed.
310 if (Element & (1 << 7))
311 ShuffleMask.push_back(SM_SentinelZero);
312 else {
313 // Only the least significant 4 bits of the byte are used.
314 int Index = Base + (Element & 0xf);
315 ShuffleMask.push_back(Index);
306316 }
307317 }
308318 }
2323
2424 namespace llvm {
2525 class Constant;
26 class DataLayout;
2627 class MVT;
2728
2829 enum { SM_SentinelUndef = -1, SM_SentinelZero = -2 };
6768 void DecodeUNPCKLMask(MVT VT, SmallVectorImpl &ShuffleMask);
6869
6970 /// \brief Decode a PSHUFB mask from an IR-level vector constant.
70 void DecodePSHUFBMask(const Constant *C, SmallVectorImpl &ShuffleMask);
71 void DecodePSHUFBMask(const Constant *C, const DataLayout *TD,
72 SmallVectorImpl &ShuffleMask);
7173
7274 /// \brief Decode a PSHUFB mask from a raw array of constants such as from
7375 /// BUILD_VECTOR.
53645364 /// IsUnary to true if only uses one source. Note that this will set IsUnary for
53655365 /// shuffles which use a single input multiple times, and in those cases it will
53665366 /// adjust the mask to only have indices within that single input.
5367 static bool getTargetShuffleMask(SDNode *N, MVT VT,
5367 static bool getTargetShuffleMask(SDNode *N, MVT VT, const DataLayout *TD,
53685368 SmallVectorImpl &Mask, bool &IsUnary) {
53695369 unsigned NumElems = VT.getVectorNumElements();
53705370 SDValue ImmN;
54715471 return false;
54725472
54735473 if (auto *C = dyn_cast(MaskCP->getConstVal())) {
5474 // FIXME: Support AVX-512 here.
5475 Type *Ty = C->getType();
5476 if (!Ty->isVectorTy() || (Ty->getVectorNumElements() != 16 &&
5477 Ty->getVectorNumElements() != 32))
5478 return false;
5479
5480 DecodePSHUFBMask(C, Mask);
5474 DecodePSHUFBMask(C, TD, Mask);
54815475 break;
54825476 }
54835477
55405534 SDValue V = SDValue(N, 0);
55415535 EVT VT = V.getValueType();
55425536 unsigned Opcode = V.getOpcode();
5537 const DataLayout *TD = DAG.getSubtarget().getDataLayout();
55435538
55445539 // Recurse into ISD::VECTOR_SHUFFLE node to find scalars.
55455540 if (const ShuffleVectorSDNode *SV = dyn_cast(N)) {
55615556 SmallVector ShuffleMask;
55625557 bool IsUnary;
55635558
5564 if (!getTargetShuffleMask(N, ShufVT, ShuffleMask, IsUnary))
5559 if (!getTargetShuffleMask(N, ShufVT, TD, ShuffleMask, IsUnary))
55655560 return SDValue();
55665561
55675562 int Elt = ShuffleMask[Index];
2211622111 return false;
2211722112 SmallVector OpMask;
2211822113 bool IsUnary;
22119 bool HaveMask = getTargetShuffleMask(Op.getNode(), VT, OpMask, IsUnary);
22114 bool HaveMask = getTargetShuffleMask(
22115 Op.getNode(), VT, Subtarget->getDataLayout(), OpMask, IsUnary);
2212022116 // We only can combine unary shuffles which we can decode the mask for.
2212122117 if (!HaveMask || !IsUnary)
2212222118 return false;
2220722203 ///
2220822204 /// This is a very minor wrapper around getTargetShuffleMask to easy forming v4
2220922205 /// PSHUF-style masks that can be reused with such instructions.
22210 static SmallVector getPSHUFShuffleMask(SDValue N) {
22206 static SmallVector getPSHUFShuffleMask(SDValue N,
22207 const DataLayout *TD) {
2221122208 SmallVector Mask;
2221222209 bool IsUnary;
22213 bool HaveMask = getTargetShuffleMask(N.getNode(), N.getSimpleValueType(), Mask, IsUnary);
22210 bool HaveMask = getTargetShuffleMask(N.getNode(), N.getSimpleValueType(), TD,
22211 Mask, IsUnary);
2221422212 (void)HaveMask;
2221522213 assert(HaveMask);
2221622214
2224222240 assert(N.getOpcode() == X86ISD::PSHUFD &&
2224322241 "Called with something other than an x86 128-bit half shuffle!");
2224422242 SDLoc DL(N);
22243 const DataLayout *TD = DAG.getSubtarget().getDataLayout();
2224522244
2224622245 // Walk up a single-use chain looking for a combinable shuffle. Keep a stack
2224722246 // of the shuffles in the chain so that we can form a fresh chain to replace
2232722326 return SDValue();
2232822327
2232922328 // Merge this node's mask and our incoming mask.
22330 SmallVector VMask = getPSHUFShuffleMask(V);
22329 SmallVector VMask = getPSHUFShuffleMask(V, TD);
2233122330 for (int &M : Mask)
2233222331 M = VMask[M];
2233322332 V = DAG.getNode(V.getOpcode(), DL, V.getValueType(), V.getOperand(0),
2237622375 "Called with something other than an x86 128-bit half shuffle!");
2237722376 SDLoc DL(N);
2237822377 unsigned CombineOpcode = N.getOpcode();
22378 const DataLayout *TD = DAG.getSubtarget().getDataLayout();
2237922379
2238022380 // Walk up a single-use chain looking for a combinable shuffle.
2238122381 SDValue V = N.getOperand(0);
2241422414
2241522415 // Merge this node's mask and our incoming mask (adjusted to account for all
2241622416 // the pshufd instructions encountered).
22417 SmallVector VMask = getPSHUFShuffleMask(V);
22417 SmallVector VMask = getPSHUFShuffleMask(V, TD);
2241822418 for (int &M : Mask)
2241922419 M = VMask[M];
2242022420 V = DAG.getNode(V.getOpcode(), DL, MVT::v8i16, V.getOperand(0),
2243622436 const X86Subtarget *Subtarget) {
2243722437 SDLoc DL(N);
2243822438 MVT VT = N.getSimpleValueType();
22439 const DataLayout *TD = Subtarget->getDataLayout();
2243922440 SmallVector Mask;
2244022441
2244122442 switch (N.getOpcode()) {
2244222443 case X86ISD::PSHUFD:
2244322444 case X86ISD::PSHUFLW:
2244422445 case X86ISD::PSHUFHW:
22445 Mask = getPSHUFShuffleMask(N);
22446 Mask = getPSHUFShuffleMask(N, TD);
2244622447 assert(Mask.size() == 4);
2244722448 break;
2244822449 default:
2249422495 while (D.getOpcode() == ISD::BITCAST && D.hasOneUse())
2249522496 D = D.getOperand(0);
2249622497 if (D.getOpcode() == X86ISD::PSHUFD && D.hasOneUse()) {
22497 SmallVector VMask = getPSHUFShuffleMask(V);
22498 SmallVector DMask = getPSHUFShuffleMask(D);
22498 SmallVector VMask = getPSHUFShuffleMask(V, TD);
22499 SmallVector DMask = getPSHUFShuffleMask(D, TD);
2249922500 int NOffset = N.getOpcode() == X86ISD::PSHUFLW ? 0 : 4;
2250022501 int VOffset = V.getOpcode() == X86ISD::PSHUFLW ? 0 : 4;
2250122502 int WordMask[8];
2274822749 if (!InVec.hasOneUse())
2274922750 return SDValue();
2275022751
22752 const DataLayout *TD = DAG.getSubtarget().getDataLayout();
2275122753 SmallVector ShuffleMask;
2275222754 bool UnaryShuffle;
22753 if (!getTargetShuffleMask(InVec.getNode(), CurrentVT.getSimpleVT(),
22755 if (!getTargetShuffleMask(InVec.getNode(), CurrentVT.getSimpleVT(), TD,
2275422756 ShuffleMask, UnaryShuffle))
2275522757 return SDValue();
2275622758
11601160
11611161 if (auto *C = getConstantFromPool(*MI, MaskOp)) {
11621162 SmallVector Mask;
1163 DecodePSHUFBMask(C, Mask);
1163 DecodePSHUFBMask(C, TM.getSubtargetImpl()->getDataLayout(), Mask);
11641164 if (!Mask.empty())
11651165 OutStreamer.AddComment(getShuffleComment(DstOp, SrcOp, Mask));
11661166 }
2626 ret <16 x i8> %1
2727 }
2828
29 ; Test that we won't crash when the constant was reused for another instruction.
30
31 define <16 x i8> @test4(<2 x i64>* %V) {
32 ; CHECK-LABEL: test4
33 ; CHECK: pshufb {{.*}}# xmm0 = xmm0[8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7]
34 store <2 x i64> , <2 x i64>* %V, align 16
35 %1 = tail call <16 x i8> @llvm.x86.ssse3.pshuf.b.128(<16 x i8> undef, <16 x i8> )
36 ret <16 x i8> %1
37 }
38
2939 declare <16 x i8> @llvm.x86.ssse3.pshuf.b.128(<16 x i8>, <16 x i8>) nounwind readnone