1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[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.
This commit is contained in:
Simon Pilgrim 2020-08-12 17:41:09 +01:00
parent 9a34dd9cc6
commit 1c995f64f2

View File

@ -10754,6 +10754,27 @@ static bool isRepeatedTargetShuffleMask(unsigned LaneSizeInBits, MVT VT,
return true;
}
/// Checks whether the vector elements referenced by two shuffle masks are
/// equivalent.
static bool IsElementEquivalent(int MaskSize, SDValue Op, SDValue ExpectedOp,
int Idx, int ExpectedIdx) {
assert(0 <= Idx && Idx < MaskSize && 0 <= ExpectedIdx &&
ExpectedIdx < MaskSize && "Out of range element index");
if (!Op || !ExpectedOp || Op.getOpcode() != ExpectedOp.getOpcode())
return false;
if (Op.getOpcode() == ISD::BUILD_VECTOR) {
// If the values are build vectors, we can look through them to find
// equivalent inputs that make the shuffles equivalent.
// TODO: Handle MaskSize != Op.getNumOperands()?
if (MaskSize == Op.getNumOperands() &&
MaskSize == ExpectedOp.getNumOperands())
return Op.getOperand(Idx) == ExpectedOp.getOperand(ExpectedIdx);
}
return false;
}
/// Checks whether a shuffle mask is equivalent to an explicit list of
/// arguments.
///
@ -10766,28 +10787,23 @@ static bool isRepeatedTargetShuffleMask(unsigned LaneSizeInBits, MVT VT,
/// in the argument.
static bool isShuffleEquivalent(SDValue V1, SDValue V2, ArrayRef<int> Mask,
ArrayRef<int> ExpectedMask) {
if (Mask.size() != ExpectedMask.size())
return false;
int Size = Mask.size();
// If the values are build vectors, we can look through them to find
// equivalent inputs that make the shuffles equivalent.
auto *BV1 = dyn_cast<BuildVectorSDNode>(V1);
auto *BV2 = dyn_cast<BuildVectorSDNode>(V2);
if (Mask.size() != (int)ExpectedMask.size())
return false;
for (int i = 0; i < Size; ++i) {
assert(Mask[i] >= -1 && "Out of bound mask element!");
if (Mask[i] >= 0 && Mask[i] != ExpectedMask[i]) {
auto *MaskBV = Mask[i] < Size ? BV1 : BV2;
auto *ExpectedBV = ExpectedMask[i] < Size ? BV1 : BV2;
if (!MaskBV || !ExpectedBV ||
MaskBV->getOperand(Mask[i] % Size) !=
ExpectedBV->getOperand(ExpectedMask[i] % Size))
int MaskIdx = Mask[i];
int ExpectedIdx = ExpectedMask[i];
if (0 <= MaskIdx && MaskIdx != ExpectedIdx) {
SDValue MaskV = MaskIdx < Size ? V1 : V2;
SDValue ExpectedV = ExpectedIdx < Size ? V1 : V2;
MaskIdx = MaskIdx < Size ? MaskIdx : (MaskIdx - Size);
ExpectedIdx = ExpectedIdx < Size ? ExpectedIdx : (ExpectedIdx - Size);
if (!IsElementEquivalent(Size, MaskV, ExpectedV, MaskIdx, ExpectedIdx))
return false;
}
}
return true;
}
@ -10814,22 +10830,17 @@ static bool isTargetShuffleEquivalent(ArrayRef<int> Mask,
if (!isUndefOrZeroOrInRange(Mask, 0, 2 * Size))
return false;
// If the values are build vectors, we can look through them to find
// equivalent inputs that make the shuffles equivalent.
auto *BV1 = dyn_cast_or_null<BuildVectorSDNode>(V1);
auto *BV2 = dyn_cast_or_null<BuildVectorSDNode>(V2);
BV1 = ((BV1 && Size != (int)BV1->getNumOperands()) ? nullptr : BV1);
BV2 = ((BV2 && Size != (int)BV2->getNumOperands()) ? nullptr : BV2);
for (int i = 0; i < Size; ++i) {
if (Mask[i] == SM_SentinelUndef || Mask[i] == ExpectedMask[i])
int MaskIdx = Mask[i];
int ExpectedIdx = ExpectedMask[i];
if (MaskIdx == SM_SentinelUndef || MaskIdx == ExpectedIdx)
continue;
if (0 <= Mask[i] && 0 <= ExpectedMask[i]) {
auto *MaskBV = Mask[i] < Size ? BV1 : BV2;
auto *ExpectedBV = ExpectedMask[i] < Size ? BV1 : BV2;
if (MaskBV && ExpectedBV &&
MaskBV->getOperand(Mask[i] % Size) ==
ExpectedBV->getOperand(ExpectedMask[i] % Size))
SDValue MaskV = MaskIdx < Size ? V1 : V2;
SDValue ExpectedV = ExpectedIdx < Size ? V1 : V2;
MaskIdx = MaskIdx < Size ? MaskIdx : (MaskIdx - Size);
ExpectedIdx = ExpectedIdx < Size ? ExpectedIdx : (ExpectedIdx - Size);
if (IsElementEquivalent(Size, MaskV, ExpectedV, MaskIdx, ExpectedIdx))
continue;
}
// TODO - handle SM_Sentinel equivalences.