Match vpku[hw]um(x,x).
authorChris Lattner <sabre@nondot.org>
Thu, 6 Apr 2006 22:28:36 +0000 (22:28 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 6 Apr 2006 22:28:36 +0000 (22:28 +0000)
Convert vsldoi(x,x) to work the same way other (x,x) cases work.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27467 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/PPCISelLowering.cpp
lib/Target/PowerPC/PPCISelLowering.h
lib/Target/PowerPC/PPCInstrAltivec.td

index a7608657ef232641dab8a99681958acd4f535cff..686f2fa06965a37c661a0d4e5f54c323d2af3515 100644 (file)
@@ -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) ||
index 559256b4d118758caa4ce0c266b1d20f4a0685b0..c6c91af72430ed7c70e6125fa82197e52b14a8ea 100644 (file)
@@ -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
index 2120a02582fd0716b60a4bf4ce1c93b1d2e19e91..d01908e5dd237c32552199dcc14156dde83aebf0 100644 (file)
 /// 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))>;