@@ -10754,6 +10754,27 @@ static bool isRepeatedTargetShuffleMask(unsigned LaneSizeInBits, MVT VT,
10754
10754
return true;
10755
10755
}
10756
10756
10757
+ /// Checks whether the vector elements referenced by two shuffle masks are
10758
+ /// equivalent.
10759
+ static bool IsElementEquivalent(int MaskSize, SDValue Op, SDValue ExpectedOp,
10760
+ int Idx, int ExpectedIdx) {
10761
+ assert(0 <= Idx && Idx < MaskSize && 0 <= ExpectedIdx &&
10762
+ ExpectedIdx < MaskSize && "Out of range element index");
10763
+ if (!Op || !ExpectedOp || Op.getOpcode() != ExpectedOp.getOpcode())
10764
+ return false;
10765
+
10766
+ if (Op.getOpcode() == ISD::BUILD_VECTOR) {
10767
+ // If the values are build vectors, we can look through them to find
10768
+ // equivalent inputs that make the shuffles equivalent.
10769
+ // TODO: Handle MaskSize != Op.getNumOperands()?
10770
+ if (MaskSize == Op.getNumOperands() &&
10771
+ MaskSize == ExpectedOp.getNumOperands())
10772
+ return Op.getOperand(Idx) == ExpectedOp.getOperand(ExpectedIdx);
10773
+ }
10774
+
10775
+ return false;
10776
+ }
10777
+
10757
10778
/// Checks whether a shuffle mask is equivalent to an explicit list of
10758
10779
/// arguments.
10759
10780
///
@@ -10766,28 +10787,23 @@ static bool isRepeatedTargetShuffleMask(unsigned LaneSizeInBits, MVT VT,
10766
10787
/// in the argument.
10767
10788
static bool isShuffleEquivalent(SDValue V1, SDValue V2, ArrayRef<int> Mask,
10768
10789
ArrayRef<int> ExpectedMask) {
10769
- if (Mask.size() != ExpectedMask.size())
10770
- return false;
10771
-
10772
10790
int Size = Mask.size();
10773
-
10774
- // If the values are build vectors, we can look through them to find
10775
- // equivalent inputs that make the shuffles equivalent.
10776
- auto *BV1 = dyn_cast<BuildVectorSDNode>(V1);
10777
- auto *BV2 = dyn_cast<BuildVectorSDNode>(V2);
10791
+ if (Mask.size() != (int)ExpectedMask.size())
10792
+ return false;
10778
10793
10779
10794
for (int i = 0; i < Size; ++i) {
10780
10795
assert(Mask[i] >= -1 && "Out of bound mask element!");
10781
- if (Mask[i] >= 0 && Mask[i] != ExpectedMask[i]) {
10782
- auto *MaskBV = Mask[i] < Size ? BV1 : BV2;
10783
- auto *ExpectedBV = ExpectedMask[i] < Size ? BV1 : BV2;
10784
- if (!MaskBV || !ExpectedBV ||
10785
- MaskBV->getOperand(Mask[i] % Size) !=
10786
- ExpectedBV->getOperand(ExpectedMask[i] % Size))
10796
+ int MaskIdx = Mask[i];
10797
+ int ExpectedIdx = ExpectedMask[i];
10798
+ if (0 <= MaskIdx && MaskIdx != ExpectedIdx) {
10799
+ SDValue MaskV = MaskIdx < Size ? V1 : V2;
10800
+ SDValue ExpectedV = ExpectedIdx < Size ? V1 : V2;
10801
+ MaskIdx = MaskIdx < Size ? MaskIdx : (MaskIdx - Size);
10802
+ ExpectedIdx = ExpectedIdx < Size ? ExpectedIdx : (ExpectedIdx - Size);
10803
+ if (!IsElementEquivalent(Size, MaskV, ExpectedV, MaskIdx, ExpectedIdx))
10787
10804
return false;
10788
10805
}
10789
10806
}
10790
-
10791
10807
return true;
10792
10808
}
10793
10809
@@ -10814,22 +10830,17 @@ static bool isTargetShuffleEquivalent(ArrayRef<int> Mask,
10814
10830
if (!isUndefOrZeroOrInRange(Mask, 0, 2 * Size))
10815
10831
return false;
10816
10832
10817
- // If the values are build vectors, we can look through them to find
10818
- // equivalent inputs that make the shuffles equivalent.
10819
- auto *BV1 = dyn_cast_or_null<BuildVectorSDNode>(V1);
10820
- auto *BV2 = dyn_cast_or_null<BuildVectorSDNode>(V2);
10821
- BV1 = ((BV1 && Size != (int)BV1->getNumOperands()) ? nullptr : BV1);
10822
- BV2 = ((BV2 && Size != (int)BV2->getNumOperands()) ? nullptr : BV2);
10823
-
10824
10833
for (int i = 0; i < Size; ++i) {
10825
- if (Mask[i] == SM_SentinelUndef || Mask[i] == ExpectedMask[i])
10834
+ int MaskIdx = Mask[i];
10835
+ int ExpectedIdx = ExpectedMask[i];
10836
+ if (MaskIdx == SM_SentinelUndef || MaskIdx == ExpectedIdx)
10826
10837
continue;
10827
10838
if (0 <= Mask[i] && 0 <= ExpectedMask[i]) {
10828
- auto *MaskBV = Mask[i] < Size ? BV1 : BV2 ;
10829
- auto *ExpectedBV = ExpectedMask[i] < Size ? BV1 : BV2 ;
10830
- if (MaskBV && ExpectedBV &&
10831
- MaskBV->getOperand(Mask[i] % Size) ==
10832
- ExpectedBV->getOperand(ExpectedMask[i] % Size ))
10839
+ SDValue MaskV = MaskIdx < Size ? V1 : V2 ;
10840
+ SDValue ExpectedV = ExpectedIdx < Size ? V1 : V2 ;
10841
+ MaskIdx = MaskIdx < Size ? MaskIdx : (MaskIdx - Size);
10842
+ ExpectedIdx = ExpectedIdx < Size ? ExpectedIdx : (ExpectedIdx - Size);
10843
+ if (IsElementEquivalent(Size, MaskV, ExpectedV, MaskIdx, ExpectedIdx ))
10833
10844
continue;
10834
10845
}
10835
10846
// TODO - handle SM_Sentinel equivalences.
0 commit comments