diff --git a/lib/Target/X86/Utils/X86ShuffleDecode.cpp b/lib/Target/X86/Utils/X86ShuffleDecode.cpp index 69d9439568c..8b87c1f9c8a 100644 --- a/lib/Target/X86/Utils/X86ShuffleDecode.cpp +++ b/lib/Target/X86/Utils/X86ShuffleDecode.cpp @@ -64,7 +64,7 @@ void DecodeMOVLHPSMask(unsigned NElts, SmallVectorImpl &ShuffleMask) { /// 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(MVT VT, unsigned Imm, SmallVectorImpl &ShuffleMask) { unsigned NumElts = VT.getVectorNumElements(); unsigned NumLanes = VT.getSizeInBits() / 128; @@ -80,7 +80,7 @@ void DecodePSHUFMask(EVT VT, unsigned Imm, SmallVectorImpl &ShuffleMask) { } } -void DecodePSHUFHWMask(EVT VT, unsigned Imm, +void DecodePSHUFHWMask(MVT VT, unsigned Imm, SmallVectorImpl &ShuffleMask) { unsigned NumElts = VT.getVectorNumElements(); @@ -96,7 +96,7 @@ void DecodePSHUFHWMask(EVT VT, unsigned Imm, } } -void DecodePSHUFLWMask(EVT VT, unsigned Imm, +void DecodePSHUFLWMask(MVT VT, unsigned Imm, SmallVectorImpl &ShuffleMask) { unsigned NumElts = VT.getVectorNumElements(); @@ -115,7 +115,7 @@ void DecodePSHUFLWMask(EVT VT, 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(MVT VT, unsigned Imm, SmallVectorImpl &ShuffleMask) { unsigned NumElts = VT.getVectorNumElements(); unsigned NumLanes = VT.getSizeInBits() / 128; @@ -123,15 +123,12 @@ void DecodeSHUFPMask(EVT VT, unsigned Imm, SmallVectorImpl &ShuffleMask) { unsigned NewImm = Imm; for (unsigned l = 0; l != NumElts; l += NumLaneElts) { - // Part that reads from dest. - for (unsigned i = 0; i != NumLaneElts/2; ++i) { - ShuffleMask.push_back(NewImm % NumLaneElts + l); - NewImm /= NumLaneElts; - } - // Part that reads from src. - for (unsigned i = 0; i != NumLaneElts/2; ++i) { - ShuffleMask.push_back(NewImm % NumLaneElts + NumElts + l); - NewImm /= NumLaneElts; + // each half of a lane comes from different source + for (unsigned s = 0; s != NumElts*2; s += NumElts) { + for (unsigned i = 0; i != NumLaneElts/2; ++i) { + ShuffleMask.push_back(NewImm % NumLaneElts + s + l); + NewImm /= NumLaneElts; + } } if (NumLaneElts == 4) NewImm = Imm; // reload imm } @@ -140,7 +137,7 @@ 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(MVT VT, SmallVectorImpl &ShuffleMask) { unsigned NumElts = VT.getVectorNumElements(); // Handle 128 and 256-bit vector lengths. AVX defines UNPCK* to operate @@ -160,7 +157,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(MVT VT, SmallVectorImpl &ShuffleMask) { unsigned NumElts = VT.getVectorNumElements(); // Handle 128 and 256-bit vector lengths. AVX defines UNPCK* to operate @@ -177,19 +174,18 @@ void DecodeUNPCKLMask(EVT VT, SmallVectorImpl &ShuffleMask) { } } -void DecodeVPERM2X128Mask(EVT VT, unsigned Imm, +void DecodeVPERM2X128Mask(MVT VT, unsigned Imm, SmallVectorImpl &ShuffleMask) { if (Imm & 0x88) return; // Not a shuffle unsigned HalfSize = VT.getVectorNumElements()/2; - unsigned FstHalfBegin = (Imm & 0x3) * HalfSize; - unsigned SndHalfBegin = ((Imm >> 4) & 0x3) * HalfSize; - for (unsigned i = FstHalfBegin, e = FstHalfBegin+HalfSize; i != e; ++i) - ShuffleMask.push_back(i); - for (unsigned i = SndHalfBegin, e = SndHalfBegin+HalfSize; i != e; ++i) - ShuffleMask.push_back(i); + for (unsigned l = 0; l != 2; ++l) { + unsigned HalfBegin = ((Imm >> (l*4)) & 0x3) * HalfSize; + for (unsigned i = HalfBegin, e = HalfBegin+HalfSize; i != e; ++i) + ShuffleMask.push_back(i); + } } /// DecodeVPERMMask - this decodes the shuffle masks for VPERMQ/VPERMPD. diff --git a/lib/Target/X86/Utils/X86ShuffleDecode.h b/lib/Target/X86/Utils/X86ShuffleDecode.h index a039b70918b..70d8171a815 100644 --- a/lib/Target/X86/Utils/X86ShuffleDecode.h +++ b/lib/Target/X86/Utils/X86ShuffleDecode.h @@ -35,29 +35,29 @@ void DecodeMOVHLPSMask(unsigned NElts, SmallVectorImpl &ShuffleMask); // <0,2> or <0,1,4,5> void DecodeMOVLHPSMask(unsigned NElts, SmallVectorImpl &ShuffleMask); -void DecodePSHUFMask(EVT VT, unsigned Imm, SmallVectorImpl &ShuffleMask); +void DecodePSHUFMask(MVT VT, unsigned Imm, SmallVectorImpl &ShuffleMask); -void DecodePSHUFHWMask(EVT VT, unsigned Imm, SmallVectorImpl &ShuffleMask); +void DecodePSHUFHWMask(MVT VT, unsigned Imm, SmallVectorImpl &ShuffleMask); -void DecodePSHUFLWMask(EVT, unsigned Imm, SmallVectorImpl &ShuffleMask); +void DecodePSHUFLWMask(MVT, 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(MVT 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(MVT 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(MVT VT, SmallVectorImpl &ShuffleMask); -void DecodeVPERM2X128Mask(EVT VT, unsigned Imm, +void DecodeVPERM2X128Mask(MVT VT, unsigned Imm, SmallVectorImpl &ShuffleMask); /// DecodeVPERMMask - this decodes the shuffle masks for VPERMQ/VPERMPD. diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index e282617e3e0..3e631382715 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -4417,7 +4417,7 @@ static SDValue getShuffleVectorZeroOrUndef(SDValue V2, unsigned Idx, /// getTargetShuffleMask - Calculates the shuffle mask corresponding to the /// target specific opcode. Returns true if the Mask could be calculated. /// Sets IsUnary to true if only uses one source. -static bool getTargetShuffleMask(SDNode *N, EVT VT, +static bool getTargetShuffleMask(SDNode *N, MVT VT, SmallVectorImpl &Mask, bool &IsUnary) { unsigned NumElems = VT.getVectorNumElements(); SDValue ImmN; @@ -4518,20 +4518,21 @@ static SDValue getShuffleScalarElt(SDNode *N, unsigned Index, SelectionDAG &DAG, // Recurse into target specific vector shuffles to find scalars. if (isTargetShuffle(Opcode)) { - unsigned NumElems = VT.getVectorNumElements(); + MVT ShufVT = V.getValueType().getSimpleVT(); + unsigned NumElems = ShufVT.getVectorNumElements(); SmallVector ShuffleMask; SDValue ImmN; bool IsUnary; - if (!getTargetShuffleMask(N, VT, ShuffleMask, IsUnary)) + if (!getTargetShuffleMask(N, ShufVT, ShuffleMask, IsUnary)) return SDValue(); int Elt = ShuffleMask[Index]; if (Elt < 0) - return DAG.getUNDEF(VT.getVectorElementType()); + return DAG.getUNDEF(ShufVT.getVectorElementType()); SDValue NewV = (Elt < (int)NumElems) ? N->getOperand(0) - : N->getOperand(1); + : N->getOperand(1); return getShuffleScalarElt(NewV.getNode(), Elt % NumElems, DAG, Depth+1); } @@ -13266,7 +13267,8 @@ static SDValue XFormVExtractWithShuffleIntoLoad(SDNode *N, SelectionDAG &DAG, SmallVector ShuffleMask; bool UnaryShuffle; - if (!getTargetShuffleMask(InVec.getNode(), VT, ShuffleMask, UnaryShuffle)) + if (!getTargetShuffleMask(InVec.getNode(), VT.getSimpleVT(), ShuffleMask, + UnaryShuffle)) return SDValue(); // Select the input vector, guarding against out of range extract vector.