[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrSSE.td

Evan Cheng evan.cheng at apple.com
Wed Mar 22 00:01:33 PST 2006



Changes in directory llvm/lib/Target/X86:

X86ISelLowering.cpp updated: 1.117 -> 1.118
X86ISelLowering.h updated: 1.35 -> 1.36
X86InstrSSE.td updated: 1.14 -> 1.15
---
Log message:

- VECTOR_SHUFFLE of v4i32 / v4f32 with undef second vector always matches
  PSHUFD. We can make permutes entries which point to the undef pointing
  anything we want.
- Change some names to appease Chris.


---
Diffs of the changes:  (+55 -45)

 X86ISelLowering.cpp |   52 +++++++++++++++++++++++++++-------------------------
 X86ISelLowering.h   |   15 ++++++++-------
 X86InstrSSE.td      |   33 ++++++++++++++++++++-------------
 3 files changed, 55 insertions(+), 45 deletions(-)


Index: llvm/lib/Target/X86/X86ISelLowering.cpp
diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.117 llvm/lib/Target/X86/X86ISelLowering.cpp:1.118
--- llvm/lib/Target/X86/X86ISelLowering.cpp:1.117	Tue Mar 21 22:18:34 2006
+++ llvm/lib/Target/X86/X86ISelLowering.cpp	Wed Mar 22 02:01:21 2006
@@ -1368,27 +1368,6 @@
           (GV->isExternal() && !GV->hasNotBeenReadFromBytecode()));
 }
 
-/// isPSHUFDMask - Return true if the specified VECTOR_SHUFFLE operand
-/// specifies a shuffle of elements that is suitable for input to PSHUFD.
-bool X86::isPSHUFDMask(SDNode *N) {
-  assert(N->getOpcode() == ISD::BUILD_VECTOR);
-
-  if (N->getNumOperands() != 4)
-    return false;
-
-  // This is a splat operation if each element of the permute is the same, and
-  // if the value doesn't reference the second vector.
-  SDOperand Elt = N->getOperand(0);
-  assert(isa<ConstantSDNode>(Elt) && "Invalid VECTOR_SHUFFLE mask!");
-  for (unsigned i = 1, e = N->getNumOperands(); i != e; ++i) {
-    assert(isa<ConstantSDNode>(N->getOperand(i)) &&
-           "Invalid VECTOR_SHUFFLE mask!");
-    if (cast<ConstantSDNode>(N->getOperand(i))->getValue() >= 4) return false;
-  }
-
-  return true;
-}
-
 /// isSplatMask - Return true if the specified VECTOR_SHUFFLE operand specifies
 /// a splat of a single element.
 bool X86::isSplatMask(SDNode *N) {
@@ -1412,9 +1391,10 @@
   return cast<ConstantSDNode>(Elt)->getValue() < N->getNumOperands();
 }
 
-/// getShuffleImmediate - Return the appropriate immediate to shuffle
-/// the specified isShuffleMask VECTOR_SHUFFLE mask.
-unsigned X86::getShuffleImmediate(SDNode *N) {
+/// getShuffleSHUFImmediate - Return the appropriate immediate to shuffle
+/// the specified isShuffleMask VECTOR_SHUFFLE mask with PSHUF* and SHUFP*
+/// instructions.
+unsigned X86::getShuffleSHUFImmediate(SDNode *N) {
   unsigned NumOperands = N->getNumOperands();
   unsigned Shift = (NumOperands == 4) ? 2 : 1;
   unsigned Mask = 0;
@@ -1428,6 +1408,28 @@
   return Mask;
 }
 
+/// getShufflePSHUFDImmediate - Return the appropriate immediate to shuffle
+/// the specified isShuffleMask VECTOR_SHUFFLE mask with PSHUFD instruction.
+unsigned X86::getShufflePSHUFDImmediate(SDNode *N) {
+  unsigned NumOperands = N->getNumOperands();
+  unsigned Mask = 0;
+
+  assert(NumOperands == 4 && "Expect v4f32 / v4i32 vector operand");
+
+  unsigned i = NumOperands - 1;
+  do {
+    uint64_t Val = cast<ConstantSDNode>(N->getOperand(i))->getValue();
+    // Second vector operand must be undef. We can have it point to anything
+    // we want.
+    if (Val >= NumOperands) Val = 0;
+    Mask |= Val;
+    Mask <<= 2;
+    --i;
+  } while (i != 0);
+
+  return Mask;
+}
+
 /// LowerOperation - Provide custom lowering hooks for some operations.
 ///
 SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
@@ -2217,7 +2219,7 @@
           return DAG.getNode(X86ISD::UNPCKLP, VT, V1, V1);
         // Leave the VECTOR_SHUFFLE alone. It matches SHUFP*.
         return SDOperand();
-      } else if (VT == MVT::v4f32 && X86::isPSHUFDMask(PermMask.Val))
+      } else if (VT == MVT::v4f32)
         // Leave the VECTOR_SHUFFLE alone. It matches PSHUFD.
         return SDOperand();
     }


Index: llvm/lib/Target/X86/X86ISelLowering.h
diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.35 llvm/lib/Target/X86/X86ISelLowering.h:1.36
--- llvm/lib/Target/X86/X86ISelLowering.h:1.35	Tue Mar 21 20:53:00 2006
+++ llvm/lib/Target/X86/X86ISelLowering.h	Wed Mar 22 02:01:21 2006
@@ -179,17 +179,18 @@
 
  /// Define some predicates that are used for node matching.
  namespace X86 {
-   /// isPSHUFDMask - Return true if the specified VECTOR_SHUFFLE operand
-   /// specifies a shuffle of elements that is suitable for input to PSHUFD.
-   bool isPSHUFDMask(SDNode *N);
-
    /// isSplatMask - Return true if the specified VECTOR_SHUFFLE operand
    /// specifies a splat of a single element.
    bool isSplatMask(SDNode *N);
 
-   /// getShuffleImmediate - Return the appropriate immediate to shuffle
-   /// the specified isShuffleMask VECTOR_SHUFFLE mask.
-   unsigned getShuffleImmediate(SDNode *N);
+   /// getShuffleSHUFImmediate - Return the appropriate immediate to shuffle
+   /// the specified isShuffleMask VECTOR_SHUFFLE mask with PSHUF* and SHUFP*
+   /// instructions.
+   unsigned getShuffleSHUFImmediate(SDNode *N);
+
+   /// getShufflePSHUFDImmediate - Return the appropriate immediate to shuffle
+   /// the specified isShuffleMask VECTOR_SHUFFLE mask with PSHUFD instruction.
+   unsigned getShufflePSHUFDImmediate(SDNode *N);
  }
 
   //===----------------------------------------------------------------------===//


Index: llvm/lib/Target/X86/X86InstrSSE.td
diff -u llvm/lib/Target/X86/X86InstrSSE.td:1.14 llvm/lib/Target/X86/X86InstrSSE.td:1.15
--- llvm/lib/Target/X86/X86InstrSSE.td:1.14	Wed Mar 22 01:10:28 2006
+++ llvm/lib/Target/X86/X86InstrSSE.td	Wed Mar 22 02:01:21 2006
@@ -41,19 +41,21 @@
 def loadv4f32    : PatFrag<(ops node:$ptr), (v4f32 (load node:$ptr))>;
 def loadv2f64    : PatFrag<(ops node:$ptr), (v2f64 (load node:$ptr))>;
 
-// SHUFFLE_get_imm xform function: convert vector_shuffle mask to PSHUF*,
-// SHUF* etc. imm.
-def SHUFFLE_get_imm : SDNodeXForm<build_vector, [{
-  return getI8Imm(X86::getShuffleImmediate(N));
+// SHUFFLE_get_shuf_imm xform function: convert vector_shuffle mask to PSHUF*,
+// SHUFP* etc. imm.
+def SHUFFLE_get_shuf_imm : SDNodeXForm<build_vector, [{
+  return getI8Imm(X86::getShuffleSHUFImmediate(N));
 }]>;
 
-def SHUFFLE_splat_mask : PatLeaf<(build_vector), [{
+def SHUFFLE_get_pshufd_imm : SDNodeXForm<build_vector, [{
+  return getI8Imm(X86::getShufflePSHUFDImmediate(N));
+}]>;
+
+def SHUFP_splat_mask : PatLeaf<(build_vector), [{
   return X86::isSplatMask(N);
-}], SHUFFLE_get_imm>;
+}], SHUFFLE_get_shuf_imm>;
 
-def PSHUFD_shuffle_mask : PatLeaf<(build_vector), [{
-  return X86::isPSHUFDMask(N);
-}], SHUFFLE_get_imm>;
+def PSHUFD_shuffle_mask : PatLeaf<(build_vector), [{}], SHUFFLE_get_pshufd_imm>;
 
 //===----------------------------------------------------------------------===//
 // SSE scalar FP Instructions
@@ -801,13 +803,18 @@
 
 
 // Splat v4f32 / v4i32
-def : Pat<(vector_shuffle (v4f32 VR128:$src), (undef), SHUFFLE_splat_mask:$sm),
-          (v4f32 (SHUFPSrr VR128:$src, VR128:$src, SHUFFLE_splat_mask:$sm))>;
-def : Pat<(vector_shuffle (v4i32 VR128:$src), (undef), SHUFFLE_splat_mask:$sm),
-          (v4i32 (SHUFPSrr VR128:$src, VR128:$src, SHUFFLE_splat_mask:$sm))>;
+def : Pat<(vector_shuffle (v4f32 VR128:$src), (undef), SHUFP_splat_mask:$sm),
+          (v4f32 (SHUFPSrr VR128:$src, VR128:$src, SHUFP_splat_mask:$sm))>;
+def : Pat<(vector_shuffle (v4i32 VR128:$src), (undef), SHUFP_splat_mask:$sm),
+          (v4i32 (SHUFPSrr VR128:$src, VR128:$src, SHUFP_splat_mask:$sm))>;
 
 // Splat v2f64 / v2i64
 def : Pat<(X86unpcklp (v2f64 VR128:$src1), VR128:$src2),
           (v2f64 (UNPCKLPDrr VR128:$src1, VR128:$src2))>;
 def : Pat<(X86unpcklp (v2i64 VR128:$src1), VR128:$src2),
           (v2i64 (UNPCKLPDrr VR128:$src1, VR128:$src2))>;
+
+// Shuffle v4i32, undef
+def : Pat<(vector_shuffle (v4i32 VR128:$src1), (undef),
+           PSHUFD_shuffle_mask:$src2),
+          (v4i32 (PSHUFDrr VR128:$src1, PSHUFD_shuffle_mask:$src2))>;






More information about the llvm-commits mailing list