From a1ffc681ed7372bd371c44a6e186291b6416fe47 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Tue, 20 Mar 2012 06:42:26 +0000 Subject: [PATCH] Factor out target shuffle mask decoding from getShuffleScalarElt and use a SmallVector of int instead of unsigned for shuffle mask in decode functions. Preparation for another change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153079 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../X86/InstPrinter/X86InstComments.cpp | 10 +- lib/Target/X86/Utils/X86ShuffleDecode.cpp | 26 ++-- lib/Target/X86/Utils/X86ShuffleDecode.h | 26 ++-- lib/Target/X86/X86ISelLowering.cpp | 129 ++++++++++-------- 4 files changed, 95 insertions(+), 96 deletions(-) diff --git a/lib/Target/X86/InstPrinter/X86InstComments.cpp b/lib/Target/X86/InstPrinter/X86InstComments.cpp index 30a847f7214..19909cb6b11 100644 --- a/lib/Target/X86/InstPrinter/X86InstComments.cpp +++ b/lib/Target/X86/InstPrinter/X86InstComments.cpp @@ -29,7 +29,7 @@ using namespace llvm; void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS, const char *(*getRegName)(unsigned)) { // If this is a shuffle operation, the switch should fill in this state. - SmallVector ShuffleMask; + SmallVector ShuffleMask; const char *DestName = 0, *Src1Name = 0, *Src2Name = 0; switch (MI->getOpcode()) { @@ -500,7 +500,7 @@ void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS, if (Src1Name == Src2Name) { for (unsigned i = 0, e = ShuffleMask.size(); i != e; ++i) { if ((int)ShuffleMask[i] >= 0 && // Not sentinel. - ShuffleMask[i] >= e) // From second mask. + ShuffleMask[i] >= (int)e) // From second mask. ShuffleMask[i] -= e; } } @@ -511,20 +511,20 @@ void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS, for (unsigned i = 0, e = ShuffleMask.size(); i != e; ++i) { if (i != 0) OS << ','; - if (ShuffleMask[i] == SM_SentinelZero) { + if (ShuffleMask[i] == (int)SM_SentinelZero) { OS << "zero"; continue; } // Otherwise, it must come from src1 or src2. Print the span of elements // that comes from this src. - bool isSrc1 = ShuffleMask[i] < ShuffleMask.size(); + bool isSrc1 = ShuffleMask[i] < (int)ShuffleMask.size(); const char *SrcName = isSrc1 ? Src1Name : Src2Name; OS << (SrcName ? SrcName : "mem") << '['; bool IsFirst = true; while (i != e && (int)ShuffleMask[i] >= 0 && - (ShuffleMask[i] < ShuffleMask.size()) == isSrc1) { + (ShuffleMask[i] < (int)ShuffleMask.size()) == isSrc1) { if (!IsFirst) OS << ','; else diff --git a/lib/Target/X86/Utils/X86ShuffleDecode.cpp b/lib/Target/X86/Utils/X86ShuffleDecode.cpp index f4b85aeaf5b..32c722acc43 100644 --- a/lib/Target/X86/Utils/X86ShuffleDecode.cpp +++ b/lib/Target/X86/Utils/X86ShuffleDecode.cpp @@ -20,7 +20,7 @@ namespace llvm { -void DecodeINSERTPSMask(unsigned Imm, SmallVectorImpl &ShuffleMask) { +void DecodeINSERTPSMask(unsigned Imm, SmallVectorImpl &ShuffleMask) { // Defaults the copying the dest value. ShuffleMask.push_back(0); ShuffleMask.push_back(1); @@ -44,8 +44,7 @@ void DecodeINSERTPSMask(unsigned Imm, SmallVectorImpl &ShuffleMask) { } // <3,1> or <6,7,2,3> -void DecodeMOVHLPSMask(unsigned NElts, - SmallVectorImpl &ShuffleMask) { +void DecodeMOVHLPSMask(unsigned NElts, SmallVectorImpl &ShuffleMask) { for (unsigned i = NElts/2; i != NElts; ++i) ShuffleMask.push_back(NElts+i); @@ -54,8 +53,7 @@ void DecodeMOVHLPSMask(unsigned NElts, } // <0,2> or <0,1,4,5> -void DecodeMOVLHPSMask(unsigned NElts, - SmallVectorImpl &ShuffleMask) { +void DecodeMOVLHPSMask(unsigned NElts, SmallVectorImpl &ShuffleMask) { for (unsigned i = 0; i != NElts/2; ++i) ShuffleMask.push_back(i); @@ -66,8 +64,7 @@ void DecodeMOVLHPSMask(unsigned NElts, /// DecodePSHUFMask - This decodes the shuffle masks for pshufd, and vpermilp*. /// VT indicates the type of the vector allowing it to handle different /// datatypes and vector widths. -void DecodePSHUFMask(EVT VT, unsigned Imm, - SmallVectorImpl &ShuffleMask) { +void DecodePSHUFMask(EVT VT, unsigned Imm, SmallVectorImpl &ShuffleMask) { unsigned NumElts = VT.getVectorNumElements(); unsigned NumLanes = VT.getSizeInBits() / 128; @@ -83,8 +80,7 @@ void DecodePSHUFMask(EVT VT, unsigned Imm, } } -void DecodePSHUFHWMask(unsigned Imm, - SmallVectorImpl &ShuffleMask) { +void DecodePSHUFHWMask(unsigned Imm, SmallVectorImpl &ShuffleMask) { ShuffleMask.push_back(0); ShuffleMask.push_back(1); ShuffleMask.push_back(2); @@ -95,8 +91,7 @@ void DecodePSHUFHWMask(unsigned Imm, } } -void DecodePSHUFLWMask(unsigned Imm, - SmallVectorImpl &ShuffleMask) { +void DecodePSHUFLWMask(unsigned Imm, SmallVectorImpl &ShuffleMask) { for (unsigned i = 0; i != 4; ++i) { ShuffleMask.push_back((Imm & 3)); Imm >>= 2; @@ -110,8 +105,7 @@ void DecodePSHUFLWMask(unsigned Imm, /// DecodeSHUFPMask - This decodes the shuffle masks for shufp*. VT indicates /// the type of the vector allowing it to handle different datatypes and vector /// widths. -void DecodeSHUFPMask(EVT VT, unsigned Imm, - SmallVectorImpl &ShuffleMask) { +void DecodeSHUFPMask(EVT VT, unsigned Imm, SmallVectorImpl &ShuffleMask) { unsigned NumElts = VT.getVectorNumElements(); unsigned NumLanes = VT.getSizeInBits() / 128; @@ -136,7 +130,7 @@ void DecodeSHUFPMask(EVT VT, unsigned Imm, /// DecodeUNPCKHMask - This decodes the shuffle masks for unpckhps/unpckhpd /// and punpckh*. VT indicates the type of the vector allowing it to handle /// different datatypes and vector widths. -void DecodeUNPCKHMask(EVT VT, SmallVectorImpl &ShuffleMask) { +void DecodeUNPCKHMask(EVT VT, SmallVectorImpl &ShuffleMask) { unsigned NumElts = VT.getVectorNumElements(); // Handle 128 and 256-bit vector lengths. AVX defines UNPCK* to operate @@ -156,7 +150,7 @@ void DecodeUNPCKHMask(EVT VT, SmallVectorImpl &ShuffleMask) { /// DecodeUNPCKLMask - This decodes the shuffle masks for unpcklps/unpcklpd /// and punpckl*. VT indicates the type of the vector allowing it to handle /// different datatypes and vector widths. -void DecodeUNPCKLMask(EVT VT, SmallVectorImpl &ShuffleMask) { +void DecodeUNPCKLMask(EVT VT, SmallVectorImpl &ShuffleMask) { unsigned NumElts = VT.getVectorNumElements(); // Handle 128 and 256-bit vector lengths. AVX defines UNPCK* to operate @@ -174,7 +168,7 @@ void DecodeUNPCKLMask(EVT VT, SmallVectorImpl &ShuffleMask) { } void DecodeVPERM2X128Mask(EVT VT, unsigned Imm, - SmallVectorImpl &ShuffleMask) { + SmallVectorImpl &ShuffleMask) { unsigned HalfSize = VT.getVectorNumElements()/2; unsigned FstHalfBegin = (Imm & 0x3) * HalfSize; unsigned SndHalfBegin = ((Imm >> 4) & 0x3) * HalfSize; diff --git a/lib/Target/X86/Utils/X86ShuffleDecode.h b/lib/Target/X86/Utils/X86ShuffleDecode.h index 877c9bd5437..2f8ae1b1fcb 100644 --- a/lib/Target/X86/Utils/X86ShuffleDecode.h +++ b/lib/Target/X86/Utils/X86ShuffleDecode.h @@ -27,44 +27,38 @@ enum { SM_SentinelZero = ~0U }; -void DecodeINSERTPSMask(unsigned Imm, SmallVectorImpl &ShuffleMask); +void DecodeINSERTPSMask(unsigned Imm, SmallVectorImpl &ShuffleMask); // <3,1> or <6,7,2,3> -void DecodeMOVHLPSMask(unsigned NElts, - SmallVectorImpl &ShuffleMask); +void DecodeMOVHLPSMask(unsigned NElts, SmallVectorImpl &ShuffleMask); // <0,2> or <0,1,4,5> -void DecodeMOVLHPSMask(unsigned NElts, - SmallVectorImpl &ShuffleMask); +void DecodeMOVLHPSMask(unsigned NElts, SmallVectorImpl &ShuffleMask); -void DecodePSHUFMask(EVT VT, unsigned Imm, - SmallVectorImpl &ShuffleMask); +void DecodePSHUFMask(EVT VT, unsigned Imm, SmallVectorImpl &ShuffleMask); -void DecodePSHUFHWMask(unsigned Imm, - SmallVectorImpl &ShuffleMask); +void DecodePSHUFHWMask(unsigned Imm, SmallVectorImpl &ShuffleMask); -void DecodePSHUFLWMask(unsigned Imm, - SmallVectorImpl &ShuffleMask); +void DecodePSHUFLWMask(unsigned Imm, SmallVectorImpl &ShuffleMask); /// DecodeSHUFPMask - This decodes the shuffle masks for shufp*. VT indicates /// the type of the vector allowing it to handle different datatypes and vector /// widths. -void DecodeSHUFPMask(EVT VT, unsigned Imm, - SmallVectorImpl &ShuffleMask); +void DecodeSHUFPMask(EVT VT, unsigned Imm, SmallVectorImpl &ShuffleMask); /// DecodeUNPCKHMask - This decodes the shuffle masks for unpckhps/unpckhpd /// and punpckh*. VT indicates the type of the vector allowing it to handle /// different datatypes and vector widths. -void DecodeUNPCKHMask(EVT VT, SmallVectorImpl &ShuffleMask); +void DecodeUNPCKHMask(EVT VT, SmallVectorImpl &ShuffleMask); /// DecodeUNPCKLMask - This decodes the shuffle masks for unpcklps/unpcklpd /// and punpckl*. VT indicates the type of the vector allowing it to handle /// different datatypes and vector widths. -void DecodeUNPCKLMask(EVT VT, SmallVectorImpl &ShuffleMask); +void DecodeUNPCKLMask(EVT VT, SmallVectorImpl &ShuffleMask); void DecodeVPERM2X128Mask(EVT VT, unsigned Imm, - SmallVectorImpl &ShuffleMask); + SmallVectorImpl &ShuffleMask); } // llvm namespace diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index d90317f98d6..cad9a267823 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -4344,6 +4344,73 @@ static SDValue getShuffleVectorZeroOrUndef(SDValue V2, unsigned Idx, return DAG.getVectorShuffle(VT, V2.getDebugLoc(), V1, V2, &MaskVec[0]); } +/// getTargetShuffleMask - Calculates the shuffle mask corresponding to the +/// target specific opcode. Returns true if the Mask could be calculated. +static bool getTargetShuffleMask(SDNode *N, EVT VT, + SmallVectorImpl &Mask) { + unsigned NumElems = VT.getVectorNumElements(); + SDValue ImmN; + + switch(N->getOpcode()) { + case X86ISD::SHUFP: + ImmN = N->getOperand(N->getNumOperands()-1); + DecodeSHUFPMask(VT, cast(ImmN)->getZExtValue(), Mask); + break; + case X86ISD::UNPCKH: + DecodeUNPCKHMask(VT, Mask); + break; + case X86ISD::UNPCKL: + DecodeUNPCKLMask(VT, Mask); + break; + case X86ISD::MOVHLPS: + DecodeMOVHLPSMask(NumElems, Mask); + break; + case X86ISD::MOVLHPS: + DecodeMOVLHPSMask(NumElems, Mask); + break; + case X86ISD::PSHUFD: + case X86ISD::VPERMILP: + ImmN = N->getOperand(N->getNumOperands()-1); + DecodePSHUFMask(VT, cast(ImmN)->getZExtValue(), Mask); + break; + case X86ISD::PSHUFHW: + ImmN = N->getOperand(N->getNumOperands()-1); + DecodePSHUFHWMask(cast(ImmN)->getZExtValue(), Mask); + break; + case X86ISD::PSHUFLW: + ImmN = N->getOperand(N->getNumOperands()-1); + DecodePSHUFLWMask(cast(ImmN)->getZExtValue(), Mask); + break; + case X86ISD::MOVSS: + case X86ISD::MOVSD: { + // The index 0 always comes from the first element of the second source, + // this is why MOVSS and MOVSD are used in the first place. The other + // elements come from the other positions of the first source vector + Mask.push_back(NumElems); + for (unsigned i = 1; i != NumElems; ++i) { + Mask.push_back(i); + } + break; + } + case X86ISD::VPERM2X128: + ImmN = N->getOperand(N->getNumOperands()-1); + DecodeVPERM2X128Mask(VT, cast(ImmN)->getZExtValue(), Mask); + break; + case X86ISD::MOVDDUP: + case X86ISD::MOVLHPD: + case X86ISD::MOVLPD: + case X86ISD::MOVLPS: + case X86ISD::MOVSHDUP: + case X86ISD::MOVSLDUP: + case X86ISD::PALIGN: + // Not yet implemented + return false; + default: llvm_unreachable("unknown target shuffle node"); + } + + return true; +} + /// getShuffleScalarElt - Returns the scalar element that will make up the ith /// element of the result of the vector shuffle. static SDValue getShuffleScalarElt(SDNode *N, int Index, SelectionDAG &DAG, @@ -4371,67 +4438,11 @@ static SDValue getShuffleScalarElt(SDNode *N, int Index, SelectionDAG &DAG, // Recurse into target specific vector shuffles to find scalars. if (isTargetShuffle(Opcode)) { unsigned NumElems = VT.getVectorNumElements(); - SmallVector ShuffleMask; + SmallVector ShuffleMask; SDValue ImmN; - switch(Opcode) { - case X86ISD::SHUFP: - ImmN = N->getOperand(N->getNumOperands()-1); - DecodeSHUFPMask(VT, cast(ImmN)->getZExtValue(), - ShuffleMask); - break; - case X86ISD::UNPCKH: - DecodeUNPCKHMask(VT, ShuffleMask); - break; - case X86ISD::UNPCKL: - DecodeUNPCKLMask(VT, ShuffleMask); - break; - case X86ISD::MOVHLPS: - DecodeMOVHLPSMask(NumElems, ShuffleMask); - break; - case X86ISD::MOVLHPS: - DecodeMOVLHPSMask(NumElems, ShuffleMask); - break; - case X86ISD::PSHUFD: - case X86ISD::VPERMILP: - ImmN = N->getOperand(N->getNumOperands()-1); - DecodePSHUFMask(VT, cast(ImmN)->getZExtValue(), - ShuffleMask); - break; - case X86ISD::PSHUFHW: - ImmN = N->getOperand(N->getNumOperands()-1); - DecodePSHUFHWMask(cast(ImmN)->getZExtValue(), - ShuffleMask); - break; - case X86ISD::PSHUFLW: - ImmN = N->getOperand(N->getNumOperands()-1); - DecodePSHUFLWMask(cast(ImmN)->getZExtValue(), - ShuffleMask); - break; - case X86ISD::MOVSS: - case X86ISD::MOVSD: { - // The index 0 always comes from the first element of the second source, - // this is why MOVSS and MOVSD are used in the first place. The other - // elements come from the other positions of the first source vector. - unsigned OpNum = (Index == 0) ? 1 : 0; - return getShuffleScalarElt(V.getOperand(OpNum).getNode(), Index, DAG, - Depth+1); - } - case X86ISD::VPERM2X128: - ImmN = N->getOperand(N->getNumOperands()-1); - DecodeVPERM2X128Mask(VT, cast(ImmN)->getZExtValue(), - ShuffleMask); - break; - case X86ISD::MOVDDUP: - case X86ISD::MOVLHPD: - case X86ISD::MOVLPD: - case X86ISD::MOVLPS: - case X86ISD::MOVSHDUP: - case X86ISD::MOVSLDUP: - case X86ISD::PALIGN: - return SDValue(); // Not yet implemented. - default: llvm_unreachable("unknown target shuffle node"); - } + if (!getTargetShuffleMask(N, VT, ShuffleMask)) + return SDValue(); Index = ShuffleMask[Index]; if (Index < 0)