forked from OSchip/llvm-project
				
			[PowerPC] Swap arguments to vpkuhum/vpkuwum on little-endian
In commit r213915, Bill fixed little-endian usage of vmrgh* and vmrgl* by swapping the input arguments. As it turns out, the exact same fix is also required for the vpkuhum/vpkuwum patterns. This fixes another regression in llvmpipe when vector support is enabled. Reviewed by Bill Schmidt. llvm-svn: 214718
This commit is contained in:
		
							parent
							
								
									c36c6abc45
								
							
						
					
					
						commit
						cc9909b881
					
				| 
						 | 
					@ -852,14 +852,26 @@ static bool isConstantOrUndef(int Op, int Val) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a
 | 
					/// isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a
 | 
				
			||||||
/// VPKUHUM instruction.
 | 
					/// VPKUHUM instruction.
 | 
				
			||||||
bool PPC::isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, bool isUnary,
 | 
					/// The ShuffleKind distinguishes between big-endian operations with
 | 
				
			||||||
 | 
					/// two different inputs (0), either-endian operations with two identical
 | 
				
			||||||
 | 
					/// inputs (1), and little-endian operantion with two different inputs (2).
 | 
				
			||||||
 | 
					/// For the latter, the input operands are swapped (see PPCInstrAltivec.td).
 | 
				
			||||||
 | 
					bool PPC::isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind,
 | 
				
			||||||
                               SelectionDAG &DAG) {
 | 
					                               SelectionDAG &DAG) {
 | 
				
			||||||
  unsigned j = DAG.getTarget().getDataLayout()->isLittleEndian() ? 0 : 1;
 | 
					  if (ShuffleKind == 0) {
 | 
				
			||||||
  if (!isUnary) {
 | 
					    if (DAG.getTarget().getDataLayout()->isLittleEndian())
 | 
				
			||||||
    for (unsigned i = 0; i != 16; ++i)
 | 
					 | 
				
			||||||
      if (!isConstantOrUndef(N->getMaskElt(i),  i*2+j))
 | 
					 | 
				
			||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
  } else {
 | 
					    for (unsigned i = 0; i != 16; ++i)
 | 
				
			||||||
 | 
					      if (!isConstantOrUndef(N->getMaskElt(i), i*2+1))
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					  } else if (ShuffleKind == 2) {
 | 
				
			||||||
 | 
					    if (!DAG.getTarget().getDataLayout()->isLittleEndian())
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    for (unsigned i = 0; i != 16; ++i)
 | 
				
			||||||
 | 
					      if (!isConstantOrUndef(N->getMaskElt(i), i*2))
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					  } else if (ShuffleKind == 1) {
 | 
				
			||||||
 | 
					    unsigned j = DAG.getTarget().getDataLayout()->isLittleEndian() ? 0 : 1;
 | 
				
			||||||
    for (unsigned i = 0; i != 8; ++i)
 | 
					    for (unsigned i = 0; i != 8; ++i)
 | 
				
			||||||
      if (!isConstantOrUndef(N->getMaskElt(i),    i*2+j) ||
 | 
					      if (!isConstantOrUndef(N->getMaskElt(i),    i*2+j) ||
 | 
				
			||||||
          !isConstantOrUndef(N->getMaskElt(i+8),  i*2+j))
 | 
					          !isConstantOrUndef(N->getMaskElt(i+8),  i*2+j))
 | 
				
			||||||
| 
						 | 
					@ -870,27 +882,33 @@ bool PPC::isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, bool isUnary,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a
 | 
					/// isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a
 | 
				
			||||||
/// VPKUWUM instruction.
 | 
					/// VPKUWUM instruction.
 | 
				
			||||||
bool PPC::isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, bool isUnary,
 | 
					/// The ShuffleKind distinguishes between big-endian operations with
 | 
				
			||||||
 | 
					/// two different inputs (0), either-endian operations with two identical
 | 
				
			||||||
 | 
					/// inputs (1), and little-endian operantion with two different inputs (2).
 | 
				
			||||||
 | 
					/// For the latter, the input operands are swapped (see PPCInstrAltivec.td).
 | 
				
			||||||
 | 
					bool PPC::isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind,
 | 
				
			||||||
                               SelectionDAG &DAG) {
 | 
					                               SelectionDAG &DAG) {
 | 
				
			||||||
  unsigned j, k;
 | 
					  if (ShuffleKind == 0) {
 | 
				
			||||||
  if (DAG.getTarget().getDataLayout()->isLittleEndian()) {
 | 
					    if (DAG.getTarget().getDataLayout()->isLittleEndian())
 | 
				
			||||||
    j = 0;
 | 
					 | 
				
			||||||
    k = 1;
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    j = 2;
 | 
					 | 
				
			||||||
    k = 3;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  if (!isUnary) {
 | 
					 | 
				
			||||||
    for (unsigned i = 0; i != 16; i += 2)
 | 
					 | 
				
			||||||
      if (!isConstantOrUndef(N->getMaskElt(i  ),  i*2+j) ||
 | 
					 | 
				
			||||||
          !isConstantOrUndef(N->getMaskElt(i+1),  i*2+k))
 | 
					 | 
				
			||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
  } else {
 | 
					    for (unsigned i = 0; i != 16; i += 2)
 | 
				
			||||||
 | 
					      if (!isConstantOrUndef(N->getMaskElt(i  ),  i*2+2) ||
 | 
				
			||||||
 | 
					          !isConstantOrUndef(N->getMaskElt(i+1),  i*2+3))
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					  } else if (ShuffleKind == 2) {
 | 
				
			||||||
 | 
					    if (!DAG.getTarget().getDataLayout()->isLittleEndian())
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    for (unsigned i = 0; i != 16; i += 2)
 | 
				
			||||||
 | 
					      if (!isConstantOrUndef(N->getMaskElt(i  ),  i*2) ||
 | 
				
			||||||
 | 
					          !isConstantOrUndef(N->getMaskElt(i+1),  i*2+1))
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					  } else if (ShuffleKind == 1) {
 | 
				
			||||||
 | 
					    unsigned j = DAG.getTarget().getDataLayout()->isLittleEndian() ? 0 : 2;
 | 
				
			||||||
    for (unsigned i = 0; i != 8; i += 2)
 | 
					    for (unsigned i = 0; i != 8; i += 2)
 | 
				
			||||||
      if (!isConstantOrUndef(N->getMaskElt(i  ),  i*2+j)   ||
 | 
					      if (!isConstantOrUndef(N->getMaskElt(i  ),  i*2+j)   ||
 | 
				
			||||||
          !isConstantOrUndef(N->getMaskElt(i+1),  i*2+k) ||
 | 
					          !isConstantOrUndef(N->getMaskElt(i+1),  i*2+j+1) ||
 | 
				
			||||||
          !isConstantOrUndef(N->getMaskElt(i+8),  i*2+j)   ||
 | 
					          !isConstantOrUndef(N->getMaskElt(i+8),  i*2+j)   ||
 | 
				
			||||||
          !isConstantOrUndef(N->getMaskElt(i+9),  i*2+k))
 | 
					          !isConstantOrUndef(N->getMaskElt(i+9),  i*2+j+1))
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return true;
 | 
					  return true;
 | 
				
			||||||
| 
						 | 
					@ -6044,8 +6062,8 @@ SDValue PPCTargetLowering::LowerVECTOR_SHUFFLE(SDValue Op,
 | 
				
			||||||
    if (PPC::isSplatShuffleMask(SVOp, 1) ||
 | 
					    if (PPC::isSplatShuffleMask(SVOp, 1) ||
 | 
				
			||||||
        PPC::isSplatShuffleMask(SVOp, 2) ||
 | 
					        PPC::isSplatShuffleMask(SVOp, 2) ||
 | 
				
			||||||
        PPC::isSplatShuffleMask(SVOp, 4) ||
 | 
					        PPC::isSplatShuffleMask(SVOp, 4) ||
 | 
				
			||||||
        PPC::isVPKUWUMShuffleMask(SVOp, true, DAG) ||
 | 
					        PPC::isVPKUWUMShuffleMask(SVOp, 1, DAG) ||
 | 
				
			||||||
        PPC::isVPKUHUMShuffleMask(SVOp, true, DAG) ||
 | 
					        PPC::isVPKUHUMShuffleMask(SVOp, 1, DAG) ||
 | 
				
			||||||
        PPC::isVSLDOIShuffleMask(SVOp, true, DAG) != -1 ||
 | 
					        PPC::isVSLDOIShuffleMask(SVOp, true, DAG) != -1 ||
 | 
				
			||||||
        PPC::isVMRGLShuffleMask(SVOp, 1, 1, DAG) ||
 | 
					        PPC::isVMRGLShuffleMask(SVOp, 1, 1, DAG) ||
 | 
				
			||||||
        PPC::isVMRGLShuffleMask(SVOp, 2, 1, DAG) ||
 | 
					        PPC::isVMRGLShuffleMask(SVOp, 2, 1, DAG) ||
 | 
				
			||||||
| 
						 | 
					@ -6061,8 +6079,8 @@ SDValue PPCTargetLowering::LowerVECTOR_SHUFFLE(SDValue Op,
 | 
				
			||||||
  // and produce a fixed permutation.  If any of these match, do not lower to
 | 
					  // and produce a fixed permutation.  If any of these match, do not lower to
 | 
				
			||||||
  // VPERM.
 | 
					  // VPERM.
 | 
				
			||||||
  unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
 | 
					  unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
 | 
				
			||||||
  if (PPC::isVPKUWUMShuffleMask(SVOp, false, DAG) ||
 | 
					  if (PPC::isVPKUWUMShuffleMask(SVOp, ShuffleKind, DAG) ||
 | 
				
			||||||
      PPC::isVPKUHUMShuffleMask(SVOp, false, DAG) ||
 | 
					      PPC::isVPKUHUMShuffleMask(SVOp, ShuffleKind, DAG) ||
 | 
				
			||||||
      PPC::isVSLDOIShuffleMask(SVOp, false, DAG) != -1 ||
 | 
					      PPC::isVSLDOIShuffleMask(SVOp, false, DAG) != -1 ||
 | 
				
			||||||
      PPC::isVMRGLShuffleMask(SVOp, 1, ShuffleKind, DAG) ||
 | 
					      PPC::isVMRGLShuffleMask(SVOp, 1, ShuffleKind, DAG) ||
 | 
				
			||||||
      PPC::isVMRGLShuffleMask(SVOp, 2, ShuffleKind, DAG) ||
 | 
					      PPC::isVMRGLShuffleMask(SVOp, 2, ShuffleKind, DAG) ||
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -301,12 +301,12 @@ namespace llvm {
 | 
				
			||||||
  namespace PPC {
 | 
					  namespace PPC {
 | 
				
			||||||
    /// isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a
 | 
					    /// isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a
 | 
				
			||||||
    /// VPKUHUM instruction.
 | 
					    /// VPKUHUM instruction.
 | 
				
			||||||
    bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, bool isUnary,
 | 
					    bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind,
 | 
				
			||||||
                              SelectionDAG &DAG);
 | 
					                              SelectionDAG &DAG);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a
 | 
					    /// isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a
 | 
				
			||||||
    /// VPKUWUM instruction.
 | 
					    /// VPKUWUM instruction.
 | 
				
			||||||
    bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, bool isUnary,
 | 
					    bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind,
 | 
				
			||||||
                              SelectionDAG &DAG);
 | 
					                              SelectionDAG &DAG);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for
 | 
					    /// isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,25 +22,31 @@ def vnot_ppc : PatFrag<(ops node:$in),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def vpkuhum_shuffle : PatFrag<(ops node:$lhs, node:$rhs),
 | 
					def vpkuhum_shuffle : PatFrag<(ops node:$lhs, node:$rhs),
 | 
				
			||||||
                              (vector_shuffle node:$lhs, node:$rhs), [{
 | 
					                              (vector_shuffle node:$lhs, node:$rhs), [{
 | 
				
			||||||
  return PPC::isVPKUHUMShuffleMask(cast<ShuffleVectorSDNode>(N), false,
 | 
					  return PPC::isVPKUHUMShuffleMask(cast<ShuffleVectorSDNode>(N), 0, *CurDAG);
 | 
				
			||||||
                                   *CurDAG);
 | 
					 | 
				
			||||||
}]>;
 | 
					}]>;
 | 
				
			||||||
def vpkuwum_shuffle : PatFrag<(ops node:$lhs, node:$rhs),
 | 
					def vpkuwum_shuffle : PatFrag<(ops node:$lhs, node:$rhs),
 | 
				
			||||||
                              (vector_shuffle node:$lhs, node:$rhs), [{
 | 
					                              (vector_shuffle node:$lhs, node:$rhs), [{
 | 
				
			||||||
  return PPC::isVPKUWUMShuffleMask(cast<ShuffleVectorSDNode>(N), false,
 | 
					  return PPC::isVPKUWUMShuffleMask(cast<ShuffleVectorSDNode>(N), 0, *CurDAG);
 | 
				
			||||||
                                   *CurDAG);
 | 
					 | 
				
			||||||
}]>;
 | 
					}]>;
 | 
				
			||||||
def vpkuhum_unary_shuffle : PatFrag<(ops node:$lhs, node:$rhs),
 | 
					def vpkuhum_unary_shuffle : PatFrag<(ops node:$lhs, node:$rhs),
 | 
				
			||||||
                                    (vector_shuffle node:$lhs, node:$rhs), [{
 | 
					                                    (vector_shuffle node:$lhs, node:$rhs), [{
 | 
				
			||||||
  return PPC::isVPKUHUMShuffleMask(cast<ShuffleVectorSDNode>(N), true,
 | 
					  return PPC::isVPKUHUMShuffleMask(cast<ShuffleVectorSDNode>(N), 1, *CurDAG);
 | 
				
			||||||
                                   *CurDAG);
 | 
					 | 
				
			||||||
}]>;
 | 
					}]>;
 | 
				
			||||||
def vpkuwum_unary_shuffle : PatFrag<(ops node:$lhs, node:$rhs),
 | 
					def vpkuwum_unary_shuffle : PatFrag<(ops node:$lhs, node:$rhs),
 | 
				
			||||||
                                    (vector_shuffle node:$lhs, node:$rhs), [{
 | 
					                                    (vector_shuffle node:$lhs, node:$rhs), [{
 | 
				
			||||||
  return PPC::isVPKUWUMShuffleMask(cast<ShuffleVectorSDNode>(N), true,
 | 
					  return PPC::isVPKUWUMShuffleMask(cast<ShuffleVectorSDNode>(N), 1, *CurDAG);
 | 
				
			||||||
                                   *CurDAG);
 | 
					 | 
				
			||||||
}]>;
 | 
					}]>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// These fragments are provided for little-endian, where the inputs must be
 | 
				
			||||||
 | 
					// swapped for correct semantics.
 | 
				
			||||||
 | 
					def vpkuhum_swapped_shuffle : PatFrag<(ops node:$lhs, node:$rhs),
 | 
				
			||||||
 | 
					                                      (vector_shuffle node:$lhs, node:$rhs), [{
 | 
				
			||||||
 | 
					  return PPC::isVPKUHUMShuffleMask(cast<ShuffleVectorSDNode>(N), 2, *CurDAG);
 | 
				
			||||||
 | 
					}]>;
 | 
				
			||||||
 | 
					def vpkuwum_swapped_shuffle : PatFrag<(ops node:$lhs, node:$rhs),
 | 
				
			||||||
 | 
					                                      (vector_shuffle node:$lhs, node:$rhs), [{
 | 
				
			||||||
 | 
					  return PPC::isVPKUWUMShuffleMask(cast<ShuffleVectorSDNode>(N), 2, *CurDAG);
 | 
				
			||||||
 | 
					}]>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def vmrglb_shuffle : PatFrag<(ops node:$lhs, node:$rhs),
 | 
					def vmrglb_shuffle : PatFrag<(ops node:$lhs, node:$rhs),
 | 
				
			||||||
                             (vector_shuffle (v16i8 node:$lhs), node:$rhs), [{
 | 
					                             (vector_shuffle (v16i8 node:$lhs), node:$rhs), [{
 | 
				
			||||||
| 
						 | 
					@ -797,6 +803,14 @@ def:Pat<(vpkuwum_unary_shuffle v16i8:$vA, undef),
 | 
				
			||||||
def:Pat<(vpkuhum_unary_shuffle v16i8:$vA, undef),
 | 
					def:Pat<(vpkuhum_unary_shuffle v16i8:$vA, undef),
 | 
				
			||||||
        (VPKUHUM $vA, $vA)>;
 | 
					        (VPKUHUM $vA, $vA)>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Match vpkuwum(y,x), vpkuhum(y,x), i.e., swapped operands.
 | 
				
			||||||
 | 
					// These fragments are matched for little-endian, where the
 | 
				
			||||||
 | 
					// inputs must be swapped for correct semantics.
 | 
				
			||||||
 | 
					def:Pat<(vpkuwum_swapped_shuffle v16i8:$vA, v16i8:$vB),
 | 
				
			||||||
 | 
					        (VPKUWUM $vB, $vA)>;
 | 
				
			||||||
 | 
					def:Pat<(vpkuhum_swapped_shuffle v16i8:$vA, v16i8:$vB),
 | 
				
			||||||
 | 
					        (VPKUHUM $vB, $vA)>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Match vmrg*(x,x)
 | 
					// Match vmrg*(x,x)
 | 
				
			||||||
def:Pat<(vmrglb_unary_shuffle v16i8:$vA, undef),
 | 
					def:Pat<(vmrglb_unary_shuffle v16i8:$vA, undef),
 | 
				
			||||||
        (VMRGLB $vA, $vA)>;
 | 
					        (VMRGLB $vA, $vA)>;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,9 @@ entry:
 | 
				
			||||||
        %tmp = load <16 x i8>* %A
 | 
					        %tmp = load <16 x i8>* %A
 | 
				
			||||||
        %tmp2 = load <16 x i8>* %B
 | 
					        %tmp2 = load <16 x i8>* %B
 | 
				
			||||||
        %tmp3 = shufflevector <16 x i8> %tmp, <16 x i8> %tmp2, <16 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14, i32 16, i32 18, i32 20, i32 22, i32 24, i32 26, i32 28, i32 30>
 | 
					        %tmp3 = shufflevector <16 x i8> %tmp, <16 x i8> %tmp2, <16 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14, i32 16, i32 18, i32 20, i32 22, i32 24, i32 26, i32 28, i32 30>
 | 
				
			||||||
; CHECK: vpkuhum
 | 
					; CHECK: lvx [[REG1:[0-9]+]]
 | 
				
			||||||
 | 
					; CHECK: lvx [[REG2:[0-9]+]]
 | 
				
			||||||
 | 
					; CHECK: vpkuhum [[REG3:[0-9]+]], [[REG2]], [[REG1]]
 | 
				
			||||||
        store <16 x i8> %tmp3, <16 x i8>* %A
 | 
					        store <16 x i8> %tmp3, <16 x i8>* %A
 | 
				
			||||||
        ret void
 | 
					        ret void
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -27,7 +29,9 @@ entry:
 | 
				
			||||||
        %tmp = load <16 x i8>* %A
 | 
					        %tmp = load <16 x i8>* %A
 | 
				
			||||||
        %tmp2 = load <16 x i8>* %B
 | 
					        %tmp2 = load <16 x i8>* %B
 | 
				
			||||||
        %tmp3 = shufflevector <16 x i8> %tmp, <16 x i8> %tmp2, <16 x i32> <i32 0, i32 1, i32 4, i32 5, i32 8, i32 9, i32 12, i32 13, i32 16, i32 17, i32 20, i32 21, i32 24, i32 25, i32 28, i32 29>
 | 
					        %tmp3 = shufflevector <16 x i8> %tmp, <16 x i8> %tmp2, <16 x i32> <i32 0, i32 1, i32 4, i32 5, i32 8, i32 9, i32 12, i32 13, i32 16, i32 17, i32 20, i32 21, i32 24, i32 25, i32 28, i32 29>
 | 
				
			||||||
; CHECK: vpkuwum
 | 
					; CHECK: lvx [[REG1:[0-9]+]]
 | 
				
			||||||
 | 
					; CHECK: lvx [[REG2:[0-9]+]]
 | 
				
			||||||
 | 
					; CHECK: vpkuwum [[REG3:[0-9]+]], [[REG2]], [[REG1]]
 | 
				
			||||||
        store <16 x i8> %tmp3, <16 x i8>* %A
 | 
					        store <16 x i8> %tmp3, <16 x i8>* %A
 | 
				
			||||||
        ret void
 | 
					        ret void
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue