Skip to content

Commit 13d6cf0

Browse files
committed
[X86][SSE] Pull out BUILD_VECTOR operand equivalence tests. NFC.
Pull out element equivalence code from isShuffleEquivalent/isTargetShuffleEquivalent, I've also removed many of the index modulos where possible. First step toward simply adding some additional equivalence tests.
1 parent 5f7cdb2 commit 13d6cf0

File tree

1 file changed

+39
-28
lines changed

1 file changed

+39
-28
lines changed

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10754,6 +10754,27 @@ static bool isRepeatedTargetShuffleMask(unsigned LaneSizeInBits, MVT VT,
1075410754
return true;
1075510755
}
1075610756

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+
1075710778
/// Checks whether a shuffle mask is equivalent to an explicit list of
1075810779
/// arguments.
1075910780
///
@@ -10766,28 +10787,23 @@ static bool isRepeatedTargetShuffleMask(unsigned LaneSizeInBits, MVT VT,
1076610787
/// in the argument.
1076710788
static bool isShuffleEquivalent(SDValue V1, SDValue V2, ArrayRef<int> Mask,
1076810789
ArrayRef<int> ExpectedMask) {
10769-
if (Mask.size() != ExpectedMask.size())
10770-
return false;
10771-
1077210790
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;
1077810793

1077910794
for (int i = 0; i < Size; ++i) {
1078010795
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))
1078710804
return false;
1078810805
}
1078910806
}
10790-
1079110807
return true;
1079210808
}
1079310809

@@ -10814,22 +10830,17 @@ static bool isTargetShuffleEquivalent(ArrayRef<int> Mask,
1081410830
if (!isUndefOrZeroOrInRange(Mask, 0, 2 * Size))
1081510831
return false;
1081610832

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-
1082410833
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)
1082610837
continue;
1082710838
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))
1083310844
continue;
1083410845
}
1083510846
// TODO - handle SM_Sentinel equivalences.

0 commit comments

Comments
 (0)