forked from OSchip/llvm-project
				
			[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
							
								
									5f7cdb2eff
								
							
						
					
					
						commit
						13d6cf0951
					
				| 
						 | 
					@ -10754,6 +10754,27 @@ static bool isRepeatedTargetShuffleMask(unsigned LaneSizeInBits, MVT VT,
 | 
				
			||||||
  return true;
 | 
					  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
 | 
					/// Checks whether a shuffle mask is equivalent to an explicit list of
 | 
				
			||||||
/// arguments.
 | 
					/// arguments.
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
| 
						 | 
					@ -10766,28 +10787,23 @@ static bool isRepeatedTargetShuffleMask(unsigned LaneSizeInBits, MVT VT,
 | 
				
			||||||
/// in the argument.
 | 
					/// in the argument.
 | 
				
			||||||
static bool isShuffleEquivalent(SDValue V1, SDValue V2, ArrayRef<int> Mask,
 | 
					static bool isShuffleEquivalent(SDValue V1, SDValue V2, ArrayRef<int> Mask,
 | 
				
			||||||
                                ArrayRef<int> ExpectedMask) {
 | 
					                                ArrayRef<int> ExpectedMask) {
 | 
				
			||||||
  if (Mask.size() != ExpectedMask.size())
 | 
					 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  int Size = Mask.size();
 | 
					  int Size = Mask.size();
 | 
				
			||||||
 | 
					  if (Mask.size() != (int)ExpectedMask.size())
 | 
				
			||||||
  // If the values are build vectors, we can look through them to find
 | 
					    return false;
 | 
				
			||||||
  // equivalent inputs that make the shuffles equivalent.
 | 
					 | 
				
			||||||
  auto *BV1 = dyn_cast<BuildVectorSDNode>(V1);
 | 
					 | 
				
			||||||
  auto *BV2 = dyn_cast<BuildVectorSDNode>(V2);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (int i = 0; i < Size; ++i) {
 | 
					  for (int i = 0; i < Size; ++i) {
 | 
				
			||||||
    assert(Mask[i] >= -1 && "Out of bound mask element!");
 | 
					    assert(Mask[i] >= -1 && "Out of bound mask element!");
 | 
				
			||||||
    if (Mask[i] >= 0 && Mask[i] != ExpectedMask[i]) {
 | 
					    int MaskIdx = Mask[i];
 | 
				
			||||||
      auto *MaskBV = Mask[i] < Size ? BV1 : BV2;
 | 
					    int ExpectedIdx = ExpectedMask[i];
 | 
				
			||||||
      auto *ExpectedBV = ExpectedMask[i] < Size ? BV1 : BV2;
 | 
					    if (0 <= MaskIdx && MaskIdx != ExpectedIdx) {
 | 
				
			||||||
      if (!MaskBV || !ExpectedBV ||
 | 
					      SDValue MaskV = MaskIdx < Size ? V1 : V2;
 | 
				
			||||||
          MaskBV->getOperand(Mask[i] % Size) !=
 | 
					      SDValue ExpectedV = ExpectedIdx < Size ? V1 : V2;
 | 
				
			||||||
              ExpectedBV->getOperand(ExpectedMask[i] % Size))
 | 
					      MaskIdx = MaskIdx < Size ? MaskIdx : (MaskIdx - Size);
 | 
				
			||||||
 | 
					      ExpectedIdx = ExpectedIdx < Size ? ExpectedIdx : (ExpectedIdx - Size);
 | 
				
			||||||
 | 
					      if (!IsElementEquivalent(Size, MaskV, ExpectedV, MaskIdx, ExpectedIdx))
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					 | 
				
			||||||
  return true;
 | 
					  return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10814,22 +10830,17 @@ static bool isTargetShuffleEquivalent(ArrayRef<int> Mask,
 | 
				
			||||||
  if (!isUndefOrZeroOrInRange(Mask, 0, 2 * Size))
 | 
					  if (!isUndefOrZeroOrInRange(Mask, 0, 2 * Size))
 | 
				
			||||||
    return false;
 | 
					    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) {
 | 
					  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;
 | 
					      continue;
 | 
				
			||||||
    if (0 <= Mask[i] && 0 <= ExpectedMask[i]) {
 | 
					    if (0 <= Mask[i] && 0 <= ExpectedMask[i]) {
 | 
				
			||||||
      auto *MaskBV = Mask[i] < Size ? BV1 : BV2;
 | 
					      SDValue MaskV = MaskIdx < Size ? V1 : V2;
 | 
				
			||||||
      auto *ExpectedBV = ExpectedMask[i] < Size ? BV1 : BV2;
 | 
					      SDValue ExpectedV = ExpectedIdx < Size ? V1 : V2;
 | 
				
			||||||
      if (MaskBV && ExpectedBV &&
 | 
					      MaskIdx = MaskIdx < Size ? MaskIdx : (MaskIdx - Size);
 | 
				
			||||||
          MaskBV->getOperand(Mask[i] % Size) ==
 | 
					      ExpectedIdx = ExpectedIdx < Size ? ExpectedIdx : (ExpectedIdx - Size);
 | 
				
			||||||
              ExpectedBV->getOperand(ExpectedMask[i] % Size))
 | 
					      if (IsElementEquivalent(Size, MaskV, ExpectedV, MaskIdx, ExpectedIdx))
 | 
				
			||||||
        continue;
 | 
					        continue;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // TODO - handle SM_Sentinel equivalences.
 | 
					    // TODO - handle SM_Sentinel equivalences.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue