@@ -4654,7 +4654,8 @@ static bool isElementRotate(const std::array<std::pair<int, int>, 2> &SrcInfo,
46544654}
46554655
46564656static bool isAlternating(const std::array<std::pair<int, int>, 2> &SrcInfo,
4657- ArrayRef<int> Mask, bool RequiredPolarity) {
4657+ ArrayRef<int> Mask, unsigned Factor,
4658+ bool RequiredPolarity) {
46584659 int NumElts = Mask.size();
46594660 for (int i = 0; i != NumElts; ++i) {
46604661 int M = Mask[i];
@@ -4665,7 +4666,7 @@ static bool isAlternating(const std::array<std::pair<int, int>, 2> &SrcInfo,
46654666 bool C = Src == SrcInfo[1].first && Diff == SrcInfo[1].second;
46664667 assert(C != (Src == SrcInfo[0].first && Diff == SrcInfo[0].second) &&
46674668 "Must match exactly one of the two slides");
4668- if (RequiredPolarity != (C == i % 2))
4669+ if (RequiredPolarity != (C == (i / Factor) % 2))
46694670 return false;
46704671 }
46714672 return true;
@@ -4677,9 +4678,11 @@ static bool isAlternating(const std::array<std::pair<int, int>, 2> &SrcInfo,
46774678/// vs1: b0 b1 b2 b3
46784679/// vd: a0 b0 a2 b2
46794680static bool isZipEven(const std::array<std::pair<int, int>, 2> &SrcInfo,
4680- ArrayRef<int> Mask) {
4681- return SrcInfo[0].second == 0 && SrcInfo[1].second == 1 &&
4682- isAlternating(SrcInfo, Mask, true);
4681+ ArrayRef<int> Mask, unsigned &Factor) {
4682+ Factor = SrcInfo[1].second;
4683+ return SrcInfo[0].second == 0 && isPowerOf2_32(Factor) &&
4684+ Mask.size() % Factor == 0 &&
4685+ isAlternating(SrcInfo, Mask, Factor, true);
46834686}
46844687
46854688/// Given a shuffle which can be represented as a pair of two slides,
@@ -4690,9 +4693,11 @@ static bool isZipEven(const std::array<std::pair<int, int>, 2> &SrcInfo,
46904693/// Note that the operand order is swapped due to the way we canonicalize
46914694/// the slides, so SrCInfo[0] is vs1, and SrcInfo[1] is vs2.
46924695static bool isZipOdd(const std::array<std::pair<int, int>, 2> &SrcInfo,
4693- ArrayRef<int> Mask) {
4694- return SrcInfo[0].second == 0 && SrcInfo[1].second == -1 &&
4695- isAlternating(SrcInfo, Mask, false);
4696+ ArrayRef<int> Mask, unsigned &Factor) {
4697+ Factor = -SrcInfo[1].second;
4698+ return SrcInfo[0].second == 0 && isPowerOf2_32(Factor) &&
4699+ Mask.size() % Factor == 0 &&
4700+ isAlternating(SrcInfo, Mask, Factor, false);
46964701}
46974702
46984703// Lower a deinterleave shuffle to SRL and TRUNC. Factor must be
@@ -5779,16 +5784,33 @@ static SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG,
57795784 return convertFromScalableVector(VT, Res, DAG, Subtarget);
57805785 }
57815786
5782- if (Subtarget.hasVendorXRivosVizip() && isZipEven(SrcInfo, Mask)) {
5783- SDValue Src1 = SrcInfo[0].first == 0 ? V1 : V2;
5784- SDValue Src2 = SrcInfo[1].first == 0 ? V1 : V2;
5785- return lowerVZIP(RISCVISD::RI_VZIPEVEN_VL, Src1, Src2, DL, DAG,
5786- Subtarget);
5787- }
5788- if (Subtarget.hasVendorXRivosVizip() && isZipOdd(SrcInfo, Mask)) {
5789- SDValue Src1 = SrcInfo[1].first == 0 ? V1 : V2;
5790- SDValue Src2 = SrcInfo[0].first == 0 ? V1 : V2;
5791- return lowerVZIP(RISCVISD::RI_VZIPODD_VL, Src1, Src2, DL, DAG, Subtarget);
5787+ if (Subtarget.hasVendorXRivosVizip()) {
5788+ bool TryWiden = false;
5789+ unsigned Factor;
5790+ if (isZipEven(SrcInfo, Mask, Factor)) {
5791+ if (Factor == 1) {
5792+ SDValue Src1 = SrcInfo[0].first == 0 ? V1 : V2;
5793+ SDValue Src2 = SrcInfo[1].first == 0 ? V1 : V2;
5794+ return lowerVZIP(RISCVISD::RI_VZIPEVEN_VL, Src1, Src2, DL, DAG,
5795+ Subtarget);
5796+ }
5797+ TryWiden = true;
5798+ }
5799+ if (isZipOdd(SrcInfo, Mask, Factor)) {
5800+ if (Factor == 1) {
5801+ SDValue Src1 = SrcInfo[1].first == 0 ? V1 : V2;
5802+ SDValue Src2 = SrcInfo[0].first == 0 ? V1 : V2;
5803+ return lowerVZIP(RISCVISD::RI_VZIPODD_VL, Src1, Src2, DL, DAG,
5804+ Subtarget);
5805+ }
5806+ TryWiden = true;
5807+ }
5808+ // If we found a widening oppurtunity which would let us form a
5809+ // zipeven or zipodd, use the generic code to widen the shuffle
5810+ // and recurse through this logic.
5811+ if (TryWiden)
5812+ if (SDValue V = tryWidenMaskForShuffle(Op, DAG))
5813+ return V;
57925814 }
57935815
57945816 // Build the mask. Note that vslideup unconditionally preserves elements
0 commit comments