diff options
| author | Chris Lattner <sabre@nondot.org> | 2006-04-06 22:28:36 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2006-04-06 22:28:36 +0000 | 
| commit | a4bbfaed5c5b93e161ca5f26b05d0da1e4c94a2f (patch) | |
| tree | 7ed81008638a022d8aade77143d03ec322dfb91f /llvm/lib | |
| parent | b8fc537634ff8bc3e74a20a569c62c18aeddba3f (diff) | |
| download | bcm5719-llvm-a4bbfaed5c5b93e161ca5f26b05d0da1e4c94a2f.tar.gz bcm5719-llvm-a4bbfaed5c5b93e161ca5f26b05d0da1e4c94a2f.zip | |
Match vpku[hw]um(x,x).
Convert vsldoi(x,x) to work the same way other (x,x) cases work.
llvm-svn: 27467
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 91 | ||||
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.h | 10 | ||||
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCInstrAltivec.td | 39 | 
3 files changed, 74 insertions, 66 deletions
| diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index a7608657ef2..686f2fa0696 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -276,20 +276,36 @@ static bool isConstantOrUndef(SDOperand Op, unsigned Val) {  /// isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a  /// VPKUHUM instruction. -bool PPC::isVPKUHUMShuffleMask(SDNode *N) { -  for (unsigned i = 0; i != 16; ++i) -    if (!isConstantOrUndef(N->getOperand(i),  i*2+1)) -      return false; +bool PPC::isVPKUHUMShuffleMask(SDNode *N, bool isUnary) { +  if (!isUnary) { +    for (unsigned i = 0; i != 16; ++i) +      if (!isConstantOrUndef(N->getOperand(i),  i*2+1)) +        return false; +  } else { +    for (unsigned i = 0; i != 8; ++i) +      if (!isConstantOrUndef(N->getOperand(i),  i*2+1) || +          !isConstantOrUndef(N->getOperand(i+8),  i*2+1)) +        return false; +  }    return true;  }  /// isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a  /// VPKUWUM instruction. -bool PPC::isVPKUWUMShuffleMask(SDNode *N) { -  for (unsigned i = 0; i != 16; i += 2) -    if (!isConstantOrUndef(N->getOperand(i  ),  i*2+2) || -        !isConstantOrUndef(N->getOperand(i+1),  i*2+3)) -      return false; +bool PPC::isVPKUWUMShuffleMask(SDNode *N, bool isUnary) { +  if (!isUnary) { +    for (unsigned i = 0; i != 16; i += 2) +      if (!isConstantOrUndef(N->getOperand(i  ),  i*2+2) || +          !isConstantOrUndef(N->getOperand(i+1),  i*2+3)) +        return false; +  } else { +    for (unsigned i = 0; i != 8; i += 2) +      if (!isConstantOrUndef(N->getOperand(i  ),  i*2+2) || +          !isConstantOrUndef(N->getOperand(i+1),  i*2+3) || +          !isConstantOrUndef(N->getOperand(i+8),  i*2+2) || +          !isConstantOrUndef(N->getOperand(i+9),  i*2+3)) +        return false; +  }    return true;  } @@ -332,7 +348,7 @@ bool PPC::isVMRGHShuffleMask(SDNode *N, unsigned UnitSize, bool isUnary) {  /// isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift  /// amount, otherwise return -1. -int PPC::isVSLDOIShuffleMask(SDNode *N) { +int PPC::isVSLDOIShuffleMask(SDNode *N, bool isUnary) {    assert(N->getOpcode() == ISD::BUILD_VECTOR &&           N->getNumOperands() == 16 && "PPC only supports shuffles by bytes!");    // Find the first non-undef value in the shuffle mask. @@ -348,37 +364,17 @@ int PPC::isVSLDOIShuffleMask(SDNode *N) {    if (ShiftAmt < i) return -1;    ShiftAmt -= i; -  // Check the rest of the elements to see if they are consequtive. -  for (++i; i != 16; ++i) -    if (!isConstantOrUndef(N->getOperand(i), ShiftAmt+i)) -      return -1; -   -  return ShiftAmt; -} - -/// isVSLDOIRotateShuffleMask - If this is a vsldoi rotate shuffle mask, -/// return the shift amount, otherwise return -1.  Note that vlsdoi(x,x) will -/// result in the shuffle being changed to shuffle(x,undef, ...) with -/// transformed byte numbers. -int PPC::isVSLDOIRotateShuffleMask(SDNode *N) { -  assert(N->getNumOperands() == 16 && "PPC only supports shuffles by bytes!"); -  // Find the first non-undef value in the shuffle mask. -  unsigned i; -  for (i = 0; i != 16 && N->getOperand(i).getOpcode() == ISD::UNDEF; ++i) -    /*search*/; -   -  if (i == 16) return -1;  // all undef. -   -  // Otherwise, check to see if the rest of the elements are consequtively -  // numbered from this value. -  unsigned ShiftAmt = cast<ConstantSDNode>(N->getOperand(i))->getValue(); -  if (ShiftAmt < i) return -1; -  ShiftAmt -= i; -   -  // Check the rest of the elements to see if they are consequtive. -  for (++i; i != 16; ++i) -    if (!isConstantOrUndef(N->getOperand(i), (ShiftAmt+i) & 15)) -      return -1; +  if (!isUnary) { +    // Check the rest of the elements to see if they are consequtive. +    for (++i; i != 16; ++i) +      if (!isConstantOrUndef(N->getOperand(i), ShiftAmt+i)) +        return -1; +  } else { +    // Check the rest of the elements to see if they are consequtive. +    for (++i; i != 16; ++i) +      if (!isConstantOrUndef(N->getOperand(i), (ShiftAmt+i) & 15)) +        return -1; +  }    return ShiftAmt;  } @@ -872,7 +868,9 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {        if (PPC::isSplatShuffleMask(PermMask.Val, 1) ||            PPC::isSplatShuffleMask(PermMask.Val, 2) ||            PPC::isSplatShuffleMask(PermMask.Val, 4) || -          PPC::isVSLDOIRotateShuffleMask(PermMask.Val) != -1 || +          PPC::isVPKUWUMShuffleMask(PermMask.Val, true) || +          PPC::isVPKUHUMShuffleMask(PermMask.Val, true) || +          PPC::isVSLDOIShuffleMask(PermMask.Val, true) != -1 ||            PPC::isVMRGLShuffleMask(PermMask.Val, 1, true) ||            PPC::isVMRGLShuffleMask(PermMask.Val, 2, true) ||            PPC::isVMRGLShuffleMask(PermMask.Val, 4, true) || @@ -883,9 +881,12 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {        }      } -    if (PPC::isVPKUWUMShuffleMask(PermMask.Val) || -        PPC::isVPKUHUMShuffleMask(PermMask.Val) || -        PPC::isVSLDOIShuffleMask(PermMask.Val) != -1 || +    // Altivec has a variety of "shuffle immediates" that take two vector inputs +    // and produce a fixed permutation.  If any of these match, do not lower to +    // VPERM. +    if (PPC::isVPKUWUMShuffleMask(PermMask.Val, false) || +        PPC::isVPKUHUMShuffleMask(PermMask.Val, false) || +        PPC::isVSLDOIShuffleMask(PermMask.Val, false) != -1 ||          PPC::isVMRGLShuffleMask(PermMask.Val, 1, false) ||          PPC::isVMRGLShuffleMask(PermMask.Val, 2, false) ||          PPC::isVMRGLShuffleMask(PermMask.Val, 4, false) || diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h index 559256b4d11..c6c91af7243 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.h +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h @@ -104,11 +104,11 @@ namespace llvm {    namespace PPC {      /// isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a      /// VPKUHUM instruction. -    bool isVPKUHUMShuffleMask(SDNode *N); +    bool isVPKUHUMShuffleMask(SDNode *N, bool isUnary);      /// isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a      /// VPKUWUM instruction. -    bool isVPKUWUMShuffleMask(SDNode *N); +    bool isVPKUWUMShuffleMask(SDNode *N, bool isUnary);      /// isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for      /// a VRGL* instruction with the specified unit size (1,2 or 4 bytes). @@ -120,11 +120,7 @@ namespace llvm {      /// isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift      /// amount, otherwise return -1. -    int isVSLDOIShuffleMask(SDNode *N); - -    /// isVSLDOIRotateShuffleMask - If this is a vsldoi rotate shuffle mask, -    /// return the shift amount, otherwise return -1.  This matches vsldoi(x,x). -    int isVSLDOIRotateShuffleMask(SDNode *N); +    int isVSLDOIShuffleMask(SDNode *N, bool isUnary);      /// isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand      /// specifies a splat of a single element that is suitable for input to diff --git a/llvm/lib/Target/PowerPC/PPCInstrAltivec.td b/llvm/lib/Target/PowerPC/PPCInstrAltivec.td index 2120a02582f..d01908e5dd2 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrAltivec.td +++ b/llvm/lib/Target/PowerPC/PPCInstrAltivec.td @@ -18,12 +18,20 @@  /// VPKUHUM_shuffle_mask/VPKUWUM_shuffle_mask - Return true if this is a valid  /// shuffle mask for the VPKUHUM or VPKUWUM instructions.  def VPKUHUM_shuffle_mask : PatLeaf<(build_vector), [{ -  return PPC::isVPKUHUMShuffleMask(N); +  return PPC::isVPKUHUMShuffleMask(N, false);  }]>;  def VPKUWUM_shuffle_mask : PatLeaf<(build_vector), [{ -  return PPC::isVPKUWUMShuffleMask(N); +  return PPC::isVPKUWUMShuffleMask(N, false);  }]>; +def VPKUHUM_unary_shuffle_mask : PatLeaf<(build_vector), [{ +  return PPC::isVPKUHUMShuffleMask(N, true); +}]>; +def VPKUWUM_unary_shuffle_mask : PatLeaf<(build_vector), [{ +  return PPC::isVPKUWUMShuffleMask(N, true); +}]>; + +  def VMRGLB_shuffle_mask : PatLeaf<(build_vector), [{    return PPC::isVMRGLShuffleMask(N, 1, false);  }]>; @@ -64,20 +72,20 @@ def VMRGHW_unary_shuffle_mask : PatLeaf<(build_vector), [{  def VSLDOI_get_imm : SDNodeXForm<build_vector, [{ -  return getI32Imm(PPC::isVSLDOIShuffleMask(N)); +  return getI32Imm(PPC::isVSLDOIShuffleMask(N, false));  }]>;  def VSLDOI_shuffle_mask :  PatLeaf<(build_vector), [{ -  return PPC::isVSLDOIShuffleMask(N) != -1; +  return PPC::isVSLDOIShuffleMask(N, false) != -1;  }], VSLDOI_get_imm>; -/// VSLDOI_rotate* - These are used to match vsldoi(X,X), which is turned into +/// VSLDOI_unary* - These are used to match vsldoi(X,X), which is turned into  /// vector_shuffle(X,undef,mask) by the dag combiner. -def VSLDOI_rotate_get_imm : SDNodeXForm<build_vector, [{ -  return getI32Imm(PPC::isVSLDOIRotateShuffleMask(N)); +def VSLDOI_unary_get_imm : SDNodeXForm<build_vector, [{ +  return getI32Imm(PPC::isVSLDOIShuffleMask(N, true));  }]>; -def VSLDOI_rotate_shuffle_mask :  PatLeaf<(build_vector), [{ -  return PPC::isVSLDOIRotateShuffleMask(N) != -1; -}], VSLDOI_rotate_get_imm>; +def VSLDOI_unary_shuffle_mask :  PatLeaf<(build_vector), [{ +  return PPC::isVSLDOIShuffleMask(N, true) != -1; +}], VSLDOI_unary_get_imm>;  // VSPLT*_get_imm xform function: convert vector_shuffle mask to VSPLT* imm. @@ -581,9 +589,13 @@ def : Pat<(v4f32 (bitconvert (v4i32 VRRC:$src))), (v4f32 VRRC:$src)>;  // Shuffles. -// Match vsldoi(x,x) -def:Pat<(vector_shuffle (v16i8 VRRC:$vA),undef, VSLDOI_rotate_shuffle_mask:$in), -        (VSLDOI VRRC:$vA, VRRC:$vA, VSLDOI_rotate_shuffle_mask:$in)>; +// Match vsldoi(x,x), vpkuwum(x,x), vpkuhum(x,x) +def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef, VSLDOI_unary_shuffle_mask:$in), +        (VSLDOI VRRC:$vA, VRRC:$vA, VSLDOI_unary_shuffle_mask:$in)>; +def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef,VPKUWUM_unary_shuffle_mask:$in), +        (VPKUWUM VRRC:$vA, VRRC:$vA)>; +def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef,VPKUHUM_unary_shuffle_mask:$in), +        (VPKUHUM VRRC:$vA, VRRC:$vA)>;  // Match vmrg*(x,x)  def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef, VMRGLB_unary_shuffle_mask:$in), @@ -599,7 +611,6 @@ def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef, VMRGHH_unary_shuffle_mask:$in),  def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef, VMRGHW_unary_shuffle_mask:$in),          (VMRGHW VRRC:$vA, VRRC:$vA)>; -  // Immediate vector formation with vsplti*.  def : Pat<(v16i8 vecspltisb:$invec), (v16i8 (VSPLTISB vecspltisb:$invec))>;  def : Pat<(v16i8 vecspltish:$invec), (v16i8 (VSPLTISH vecspltish:$invec))>; | 

