@@ -4654,7 +4654,8 @@ static bool isElementRotate(const std::array<std::pair<int, int>, 2> &SrcInfo,
4654
4654
}
4655
4655
4656
4656
static 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) {
4658
4659
int NumElts = Mask.size();
4659
4660
for (int i = 0; i != NumElts; ++i) {
4660
4661
int M = Mask[i];
@@ -4665,7 +4666,7 @@ static bool isAlternating(const std::array<std::pair<int, int>, 2> &SrcInfo,
4665
4666
bool C = Src == SrcInfo[1].first && Diff == SrcInfo[1].second;
4666
4667
assert(C != (Src == SrcInfo[0].first && Diff == SrcInfo[0].second) &&
4667
4668
"Must match exactly one of the two slides");
4668
- if (RequiredPolarity != (C == i % 2))
4669
+ if (RequiredPolarity != (C == (i / Factor) % 2))
4669
4670
return false;
4670
4671
}
4671
4672
return true;
@@ -4677,9 +4678,11 @@ static bool isAlternating(const std::array<std::pair<int, int>, 2> &SrcInfo,
4677
4678
/// vs1: b0 b1 b2 b3
4678
4679
/// vd: a0 b0 a2 b2
4679
4680
static 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);
4683
4686
}
4684
4687
4685
4688
/// 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,
4690
4693
/// Note that the operand order is swapped due to the way we canonicalize
4691
4694
/// the slides, so SrCInfo[0] is vs1, and SrcInfo[1] is vs2.
4692
4695
static 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);
4696
4701
}
4697
4702
4698
4703
// Lower a deinterleave shuffle to SRL and TRUNC. Factor must be
@@ -5779,16 +5784,33 @@ static SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG,
5779
5784
return convertFromScalableVector(VT, Res, DAG, Subtarget);
5780
5785
}
5781
5786
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;
5792
5814
}
5793
5815
5794
5816
// Build the mask. Note that vslideup unconditionally preserves elements
0 commit comments