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:
parent
9a34dd9cc6
commit
1c995f64f2
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user