[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp PPCISelLowering.h PPCInstrAltivec.td

Chris Lattner lattner at cs.uiuc.edu
Thu Apr 6 15:02:54 PDT 2006



Changes in directory llvm/lib/Target/PowerPC:

PPCISelLowering.cpp updated: 1.135 -> 1.136
PPCISelLowering.h updated: 1.42 -> 1.43
PPCInstrAltivec.td updated: 1.44 -> 1.45
---
Log message:

Add support for matching vmrg(x,x) patterns


---
Diffs of the changes:  (+81 -41)

 PPCISelLowering.cpp |   72 ++++++++++++++++++++++++++++------------------------
 PPCISelLowering.h   |    4 +-
 PPCInstrAltivec.td  |   46 ++++++++++++++++++++++++++++-----
 3 files changed, 81 insertions(+), 41 deletions(-)


Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.135 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.136
--- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.135	Thu Apr  6 16:11:54 2006
+++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp	Thu Apr  6 17:02:42 2006
@@ -293,9 +293,10 @@
   return true;
 }
 
-/// isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for
-/// a VRGL* instruction with the specified unit size (1,2 or 4 bytes).
-bool PPC::isVMRGLShuffleMask(SDNode *N, unsigned UnitSize) {
+/// isVMerge - Common function, used to match vmrg* shuffles.
+///
+static bool isVMerge(SDNode *N, unsigned UnitSize, 
+                     unsigned LHSStart, unsigned RHSStart) {
   assert(N->getOpcode() == ISD::BUILD_VECTOR &&
          N->getNumOperands() == 16 && "PPC only supports shuffles by bytes!");
   assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
@@ -304,31 +305,28 @@
   for (unsigned i = 0; i != 8/UnitSize; ++i)     // Step over units
     for (unsigned j = 0; j != UnitSize; ++j) {   // Step over bytes within unit
       if (!isConstantOrUndef(N->getOperand(i*UnitSize*2+j),
-                             8+j+i*UnitSize) ||
+                             LHSStart+j+i*UnitSize) ||
           !isConstantOrUndef(N->getOperand(i*UnitSize*2+UnitSize+j),
-                             24+j+i*UnitSize))
+                             RHSStart+j+i*UnitSize))
         return false;
     }
-  return true;
+      return true;
+}
+
+/// isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for
+/// a VRGL* instruction with the specified unit size (1,2 or 4 bytes).
+bool PPC::isVMRGLShuffleMask(SDNode *N, unsigned UnitSize, bool isUnary) {
+  if (!isUnary)
+    return isVMerge(N, UnitSize, 8, 24);
+  return isVMerge(N, UnitSize, 8, 8);
 }
 
 /// isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for
 /// a VRGH* instruction with the specified unit size (1,2 or 4 bytes).
-bool PPC::isVMRGHShuffleMask(SDNode *N, unsigned UnitSize) {
-  assert(N->getOpcode() == ISD::BUILD_VECTOR &&
-         N->getNumOperands() == 16 && "PPC only supports shuffles by bytes!");
-  assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
-         "Unsupported merge size!");
-
-  for (unsigned i = 0; i != 8/UnitSize; ++i)     // Step over units
-    for (unsigned j = 0; j != UnitSize; ++j) {   // Step over bytes within unit
-      if (!isConstantOrUndef(N->getOperand(i*UnitSize*2+j),
-                             0+j+i*UnitSize) ||
-          !isConstantOrUndef(N->getOperand(i*UnitSize*2+UnitSize+j),
-                             16+j+i*UnitSize))
-        return false;
-    }
-  return true;
+bool PPC::isVMRGHShuffleMask(SDNode *N, unsigned UnitSize, bool isUnary) {
+  if (!isUnary)
+    return isVMerge(N, UnitSize, 0, 16);
+  return isVMerge(N, UnitSize, 0, 0);
 }
 
 
@@ -870,22 +868,30 @@
     // Cases that are handled by instructions that take permute immediates
     // (such as vsplt*) should be left as VECTOR_SHUFFLE nodes so they can be
     // selected by the instruction selector.
-    if (V2.getOpcode() == ISD::UNDEF && 
-        (PPC::isSplatShuffleMask(PermMask.Val, 1) ||
-         PPC::isSplatShuffleMask(PermMask.Val, 2) ||
-         PPC::isSplatShuffleMask(PermMask.Val, 4) ||
-         PPC::isVSLDOIRotateShuffleMask(PermMask.Val) != -1))
-      return Op;
+    if (V2.getOpcode() == ISD::UNDEF) {
+      if (PPC::isSplatShuffleMask(PermMask.Val, 1) ||
+          PPC::isSplatShuffleMask(PermMask.Val, 2) ||
+          PPC::isSplatShuffleMask(PermMask.Val, 4) ||
+          PPC::isVSLDOIRotateShuffleMask(PermMask.Val) != -1 ||
+          PPC::isVMRGLShuffleMask(PermMask.Val, 1, true) ||
+          PPC::isVMRGLShuffleMask(PermMask.Val, 2, true) ||
+          PPC::isVMRGLShuffleMask(PermMask.Val, 4, true) ||
+          PPC::isVMRGHShuffleMask(PermMask.Val, 1, true) ||
+          PPC::isVMRGHShuffleMask(PermMask.Val, 2, true) ||
+          PPC::isVMRGHShuffleMask(PermMask.Val, 4, true)) {
+        return Op;
+      }
+    }
     
     if (PPC::isVPKUWUMShuffleMask(PermMask.Val) ||
         PPC::isVPKUHUMShuffleMask(PermMask.Val) ||
         PPC::isVSLDOIShuffleMask(PermMask.Val) != -1 ||
-        PPC::isVMRGLShuffleMask(PermMask.Val, 1) ||
-        PPC::isVMRGLShuffleMask(PermMask.Val, 2) ||
-        PPC::isVMRGLShuffleMask(PermMask.Val, 4) ||
-        PPC::isVMRGHShuffleMask(PermMask.Val, 1) ||
-        PPC::isVMRGHShuffleMask(PermMask.Val, 2) ||
-        PPC::isVMRGHShuffleMask(PermMask.Val, 4))
+        PPC::isVMRGLShuffleMask(PermMask.Val, 1, false) ||
+        PPC::isVMRGLShuffleMask(PermMask.Val, 2, false) ||
+        PPC::isVMRGLShuffleMask(PermMask.Val, 4, false) ||
+        PPC::isVMRGHShuffleMask(PermMask.Val, 1, false) ||
+        PPC::isVMRGHShuffleMask(PermMask.Val, 2, false) ||
+        PPC::isVMRGHShuffleMask(PermMask.Val, 4, false))
       return Op;
     
     // TODO: Handle more cases, and also handle cases that are cheaper to do as


Index: llvm/lib/Target/PowerPC/PPCISelLowering.h
diff -u llvm/lib/Target/PowerPC/PPCISelLowering.h:1.42 llvm/lib/Target/PowerPC/PPCISelLowering.h:1.43
--- llvm/lib/Target/PowerPC/PPCISelLowering.h:1.42	Thu Apr  6 16:11:54 2006
+++ llvm/lib/Target/PowerPC/PPCISelLowering.h	Thu Apr  6 17:02:42 2006
@@ -112,11 +112,11 @@
 
     /// isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for
     /// a VRGL* instruction with the specified unit size (1,2 or 4 bytes).
-    bool isVMRGLShuffleMask(SDNode *N, unsigned UnitSize);
+    bool isVMRGLShuffleMask(SDNode *N, unsigned UnitSize, bool isUnary);
 
     /// isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for
     /// a VRGH* instruction with the specified unit size (1,2 or 4 bytes).
-    bool isVMRGHShuffleMask(SDNode *N, unsigned UnitSize);
+    bool isVMRGHShuffleMask(SDNode *N, unsigned UnitSize, bool isUnary);
     
     /// isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift
     /// amount, otherwise return -1.


Index: llvm/lib/Target/PowerPC/PPCInstrAltivec.td
diff -u llvm/lib/Target/PowerPC/PPCInstrAltivec.td:1.44 llvm/lib/Target/PowerPC/PPCInstrAltivec.td:1.45
--- llvm/lib/Target/PowerPC/PPCInstrAltivec.td:1.44	Thu Apr  6 16:11:54 2006
+++ llvm/lib/Target/PowerPC/PPCInstrAltivec.td	Thu Apr  6 17:02:42 2006
@@ -25,22 +25,41 @@
 }]>;
 
 def VMRGLB_shuffle_mask : PatLeaf<(build_vector), [{
-  return PPC::isVMRGLShuffleMask(N, 1);
+  return PPC::isVMRGLShuffleMask(N, 1, false);
 }]>;
 def VMRGLH_shuffle_mask : PatLeaf<(build_vector), [{
-  return PPC::isVMRGLShuffleMask(N, 2);
+  return PPC::isVMRGLShuffleMask(N, 2, false);
 }]>;
 def VMRGLW_shuffle_mask : PatLeaf<(build_vector), [{
-  return PPC::isVMRGLShuffleMask(N, 4);
+  return PPC::isVMRGLShuffleMask(N, 4, false);
 }]>;
 def VMRGHB_shuffle_mask : PatLeaf<(build_vector), [{
-  return PPC::isVMRGHShuffleMask(N, 1);
+  return PPC::isVMRGHShuffleMask(N, 1, false);
 }]>;
 def VMRGHH_shuffle_mask : PatLeaf<(build_vector), [{
-  return PPC::isVMRGHShuffleMask(N, 2);
+  return PPC::isVMRGHShuffleMask(N, 2, false);
 }]>;
 def VMRGHW_shuffle_mask : PatLeaf<(build_vector), [{
-  return PPC::isVMRGHShuffleMask(N, 4);
+  return PPC::isVMRGHShuffleMask(N, 4, false);
+}]>;
+
+def VMRGLB_unary_shuffle_mask : PatLeaf<(build_vector), [{
+  return PPC::isVMRGLShuffleMask(N, 1, true);
+}]>;
+def VMRGLH_unary_shuffle_mask : PatLeaf<(build_vector), [{
+  return PPC::isVMRGLShuffleMask(N, 2, true);
+}]>;
+def VMRGLW_unary_shuffle_mask : PatLeaf<(build_vector), [{
+  return PPC::isVMRGLShuffleMask(N, 4, true);
+}]>;
+def VMRGHB_unary_shuffle_mask : PatLeaf<(build_vector), [{
+  return PPC::isVMRGHShuffleMask(N, 1, true);
+}]>;
+def VMRGHH_unary_shuffle_mask : PatLeaf<(build_vector), [{
+  return PPC::isVMRGHShuffleMask(N, 2, true);
+}]>;
+def VMRGHW_unary_shuffle_mask : PatLeaf<(build_vector), [{
+  return PPC::isVMRGHShuffleMask(N, 4, true);
 }]>;
 
 
@@ -566,6 +585,21 @@
 def:Pat<(vector_shuffle (v16i8 VRRC:$vA),undef, VSLDOI_rotate_shuffle_mask:$in),
         (VSLDOI VRRC:$vA, VRRC:$vA, VSLDOI_rotate_shuffle_mask:$in)>;
 
+// Match vmrg*(x,x)
+def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef, VMRGLB_unary_shuffle_mask:$in),
+        (VMRGLB VRRC:$vA, VRRC:$vA)>;
+def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef, VMRGLH_unary_shuffle_mask:$in),
+        (VMRGLH VRRC:$vA, VRRC:$vA)>;
+def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef, VMRGLW_unary_shuffle_mask:$in),
+        (VMRGLW VRRC:$vA, VRRC:$vA)>;
+def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef, VMRGHB_unary_shuffle_mask:$in),
+        (VMRGHB VRRC:$vA, VRRC:$vA)>;
+def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef, VMRGHH_unary_shuffle_mask:$in),
+        (VMRGHH VRRC:$vA, VRRC:$vA)>;
+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))>;






More information about the llvm-commits mailing list