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

Chris Lattner lattner at cs.uiuc.edu
Sun Mar 19 17:54:05 PST 2006



Changes in directory llvm/lib/Target/PowerPC:

PPCISelLowering.cpp updated: 1.100 -> 1.101
PPCISelLowering.h updated: 1.27 -> 1.28
PPCInstrInfo.td updated: 1.192 -> 1.193
---
Log message:

Custom lower arbitrary VECTOR_SHUFFLE's to VPERM.
TODO: leave specific ones as VECTOR_SHUFFLE's and turn them into specialized
operations like vsplt*


---
Diffs of the changes:  (+60 -15)

 PPCISelLowering.cpp |   46 +++++++++++++++++++++++++++++++++++++++++-----
 PPCISelLowering.h   |    4 ++++
 PPCInstrInfo.td     |   25 +++++++++++++++----------
 3 files changed, 60 insertions(+), 15 deletions(-)


Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.100 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.101
--- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.100	Sun Mar 19 00:55:52 2006
+++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp	Sun Mar 19 19:53:53 2006
@@ -167,6 +167,11 @@
     setOperationAction(ISD::SUB , (MVT::ValueType)VT, Expand);
     setOperationAction(ISD::MUL , (MVT::ValueType)VT, Expand);
     setOperationAction(ISD::LOAD, (MVT::ValueType)VT, Expand);
+    setOperationAction(ISD::VECTOR_SHUFFLE, (MVT::ValueType)VT, Expand);
+    
+    // FIXME: We don't support any BUILD_VECTOR's yet.  We should custom expand
+    // the ones we do, like splat(0.0) and splat(-0.0).
+    setOperationAction(ISD::BUILD_VECTOR, (MVT::ValueType)VT, Expand);
   }
 
   if (TM.getSubtarget<PPCSubtarget>().hasAltivec()) {
@@ -179,11 +184,11 @@
     setOperationAction(ISD::LOAD       , MVT::v4f32, Legal);
     setOperationAction(ISD::ADD        , MVT::v4i32, Legal);
     setOperationAction(ISD::LOAD       , MVT::v4i32, Legal);
-    // FIXME: We don't support any BUILD_VECTOR's yet.  We should custom expand
-    // the ones we do!
-    setOperationAction(ISD::BUILD_VECTOR, MVT::v4f32, Expand);
-    setOperationAction(ISD::BUILD_VECTOR, MVT::v4i32, Expand);
-    
+    setOperationAction(ISD::LOAD       , MVT::v16i8, Legal);
+
+    setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v4i32, Custom);
+    setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v4f32, Custom);
+
     setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4f32, Custom);
     setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4i32, Custom);
   }
@@ -209,6 +214,7 @@
   case PPCISD::VMADDFP:       return "PPCISD::VMADDFP";
   case PPCISD::VNMSUBFP:      return "PPCISD::VNMSUBFP";
   case PPCISD::LVE_X:         return "PPCISD::LVE_X";
+  case PPCISD::VPERM:         return "PPCISD::VPERM";
   case PPCISD::Hi:            return "PPCISD::Hi";
   case PPCISD::Lo:            return "PPCISD::Lo";
   case PPCISD::GlobalBaseReg: return "PPCISD::GlobalBaseReg";
@@ -566,6 +572,36 @@
     return DAG.getNode(PPCISD::LVE_X, Op.getValueType(), Store, FIdx, 
                        DAG.getSrcValue(NULL));
   }
+  case ISD::VECTOR_SHUFFLE: {
+    // FIXME: Cases that are handled by instructions that take permute
+    // immediates (such as vsplt*) shouldn't be lowered here!  Also handle cases
+    // that are cheaper to do as multiple such instructions than as a constant
+    // pool load/vperm pair.
+    
+    // Lower this to a VPERM(V1, V2, V3) expression, where V3 is a constant
+    // vector that will get spilled to the constant pool.
+    SDOperand V1 = Op.getOperand(0);
+    SDOperand V2 = Op.getOperand(1);
+    if (V2.getOpcode() == ISD::UNDEF) V2 = V1;
+    SDOperand PermMask = Op.getOperand(2);
+    
+    // The SHUFFLE_VECTOR mask is almost exactly what we want for vperm, except
+    // that it is in input element units, not in bytes.  Convert now.
+    MVT::ValueType EltVT = MVT::getVectorBaseType(V1.getValueType());
+    unsigned BytesPerElement = MVT::getSizeInBits(EltVT)/8;
+    
+    std::vector<SDOperand> ResultMask;
+    for (unsigned i = 0, e = PermMask.getNumOperands(); i != e; ++i) {
+      unsigned SrcElt =cast<ConstantSDNode>(PermMask.getOperand(i))->getValue();
+      
+      for (unsigned j = 0; j != BytesPerElement; ++j)
+        ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,
+                                             MVT::i8));
+    }
+    
+    SDOperand VPermMask =DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8, ResultMask);
+    return DAG.getNode(PPCISD::VPERM, V1.getValueType(), V1, V2, VPermMask);
+  }
   }
   return SDOperand();
 }


Index: llvm/lib/Target/PowerPC/PPCISelLowering.h
diff -u llvm/lib/Target/PowerPC/PPCISelLowering.h:1.27 llvm/lib/Target/PowerPC/PPCISelLowering.h:1.28
--- llvm/lib/Target/PowerPC/PPCISelLowering.h:1.27	Sun Mar 19 00:55:52 2006
+++ llvm/lib/Target/PowerPC/PPCISelLowering.h	Sun Mar 19 19:53:53 2006
@@ -56,6 +56,10 @@
       /// the third is the SRCVALUE node.
       LVE_X,
       
+      /// VPERM - The PPC VPERM Instruction.
+      ///
+      VPERM,
+      
       /// Hi/Lo - These represent the high and low 16-bit parts of a global
       /// address respectively.  These nodes have two operands, the first of
       /// which must be a TargetGlobalAddress, and the second of which must be a


Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td
diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.192 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.193
--- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.192	Sun Mar 19 19:00:56 2006
+++ llvm/lib/Target/PowerPC/PPCInstrInfo.td	Sun Mar 19 19:53:53 2006
@@ -26,6 +26,10 @@
 def SDT_PPCCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
 def SDT_PPCRetFlag : SDTypeProfile<0, 0, []>;
 
+def SDT_PPCvperm   : SDTypeProfile<1, 3, [
+  SDTCisVT<3, v16i8>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>
+]>;
+
 //===----------------------------------------------------------------------===//
 // PowerPC specific DAG Nodes.
 //
@@ -46,6 +50,7 @@
 def PPCvnmsubfp : SDNode<"PPCISD::VNMSUBFP", SDTFPTernaryOp, []>;
 
 def PPClve_x    : SDNode<"PPCISD::LVE_X", SDTLoad, [SDNPHasChain]>;
+def PPCvperm    : SDNode<"PPCISD::VPERM", SDT_PPCvperm, []>;
 
 // These nodes represent the 32-bit PPC shifts that operate on 6-bit shift
 // amounts.  These nodes are generated by the multi-precision shift code.
@@ -118,15 +123,6 @@
   return ((unsigned)N->getValue() & 0xFFFF0000U) == (unsigned)N->getValue();
 }], HI16>;
 
-/*
-// Example of a legalize expander: Only for PPC64.
-def : Expander<(set i64:$dst, (fp_to_sint f64:$src)),
-               [(set f64:$tmp , (FCTIDZ f64:$src)),
-                (set i32:$tmpFI, (CreateNewFrameIndex 8, 8)),
-                (store f64:$tmp, i32:$tmpFI),
-                (set i64:$dst, (load i32:$tmpFI))],
-                Subtarget_PPC64>;
-*/
 
 //===----------------------------------------------------------------------===//
 // PowerPC Flag Definitions.
@@ -956,7 +952,9 @@
                        Requires<[FPContractions]>;
 
 def VPERM   : VAForm_1<43, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB, VRRC:$vC),
-                       "vperm $vD, $vA, $vC, $vB", VecFP, []>;
+                       "vperm $vD, $vA, $vC, $vB", VecFP,
+                       [(set VRRC:$vD,
+                             (PPCvperm (v4f32 VRRC:$vA), VRRC:$vB, VRRC:$vC))]>;
 
 
 // VX-Form instructions.  AltiVec arithmetic ops.
@@ -1153,6 +1151,13 @@
 
 def : Pat<(v4i32 (load xoaddr:$src)),
           (v4i32 (LVX xoaddr:$src))>;
+def : Pat<(v16i8 (load xoaddr:$src)),
+          (v16i8 (LVX xoaddr:$src))>;
+
+
+def : Pat<(PPCvperm (v4i32 VRRC:$vA), VRRC:$vB, VRRC:$vC),
+          (v4i32 (VPERM VRRC:$vA, VRRC:$vB, VRRC:$vC))>;
+
 def : Pat<(store (v4i32 VRRC:$rS), xoaddr:$dst),
           (STVX (v4i32 VRRC:$rS), xoaddr:$dst)>;
 def : Pat<(v4i32 (PPClve_x xoaddr:$src)),






More information about the llvm-commits mailing list