[llvm] r204873 - [PowerPC] Generate VSX permutations for v2[fi]64 vectors

Hal Finkel hfinkel at anl.gov
Wed Mar 26 15:58:38 PDT 2014


Author: hfinkel
Date: Wed Mar 26 17:58:37 2014
New Revision: 204873

URL: http://llvm.org/viewvc/llvm-project?rev=204873&view=rev
Log:
[PowerPC] Generate VSX permutations for v2[fi]64 vectors

Modified:
    llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
    llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
    llvm/trunk/lib/Target/PowerPC/PPCInstrVSX.td
    llvm/trunk/test/CodeGen/PowerPC/vsx.ll

Modified: llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp?rev=204873&r1=204872&r2=204873&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Wed Mar 26 17:58:37 2014
@@ -1336,6 +1336,43 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *
     }
 
     break;
+  case ISD::VECTOR_SHUFFLE:
+    if (PPCSubTarget.hasVSX() && (N->getValueType(0) == MVT::v2f64 ||
+                                  N->getValueType(0) == MVT::v2i64)) {
+      ShuffleVectorSDNode *SVN = cast<ShuffleVectorSDNode>(N);
+      
+      SDValue Op1 = N->getOperand(SVN->getMaskElt(0) < 2 ? 0 : 1),
+              Op2 = N->getOperand(SVN->getMaskElt(1) < 2 ? 0 : 1);
+      unsigned DM[2];
+
+      for (int i = 0; i < 2; ++i)
+        if (SVN->getMaskElt(i) <= 0 || SVN->getMaskElt(i) == 2)
+          DM[i] = 0;
+        else
+          DM[i] = 1;
+
+      SDValue DMV = CurDAG->getTargetConstant(DM[0] | (DM[1] << 1), MVT::i32);
+
+      if (Op1 == Op2 && DM[0] == 0 && DM[1] == 0 &&
+          Op1.getOpcode() == ISD::SCALAR_TO_VECTOR &&
+          isa<LoadSDNode>(Op1.getOperand(0))) {
+        LoadSDNode *LD = cast<LoadSDNode>(Op1.getOperand(0));
+        SDValue Base, Offset;
+
+        if (LD->isUnindexed() &&
+            SelectAddrIdxOnly(LD->getBasePtr(), Base, Offset)) {
+          SDValue Chain = LD->getChain();
+          SDValue Ops[] = { Base, Offset, Chain };
+          return CurDAG->SelectNodeTo(N, PPC::LXVDSX,
+                                      N->getValueType(0), Ops, 3);
+        }
+      }
+
+      SDValue Ops[] = { Op1, Op2, DMV };
+      return CurDAG->SelectNodeTo(N, PPC::XXPERMDI, N->getValueType(0), Ops, 3);
+    }
+
+    break;
   case PPCISD::BDNZ:
   case PPCISD::BDZ: {
     bool IsPPC64 = PPCSubTarget.isPPC64();

Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=204873&r1=204872&r2=204873&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Wed Mar 26 17:58:37 2014
@@ -570,6 +570,8 @@ PPCTargetLowering::PPCTargetLowering(PPC
       setOperationAction(ISD::LOAD, MVT::v2f64, Legal);
       setOperationAction(ISD::STORE, MVT::v2f64, Legal);
 
+      setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v2f64, Legal);
+
       addRegisterClass(MVT::f64, &PPC::VSRCRegClass);
 
       addRegisterClass(MVT::v4f32, &PPC::VSRCRegClass);
@@ -584,6 +586,8 @@ PPCTargetLowering::PPCTargetLowering(PPC
       setOperationAction(ISD::STORE, MVT::v2i64, Promote);
       AddPromotedToType (ISD::STORE, MVT::v2i64, MVT::v2f64);
 
+      setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v2i64, Legal);
+
       setOperationAction(ISD::SINT_TO_FP, MVT::v2i64, Legal);
       setOperationAction(ISD::UINT_TO_FP, MVT::v2i64, Legal);
       setOperationAction(ISD::FP_TO_SINT, MVT::v2i64, Legal);
@@ -872,8 +876,8 @@ bool PPC::isVPKUWUMShuffleMask(ShuffleVe
 ///
 static bool isVMerge(ShuffleVectorSDNode *N, unsigned UnitSize,
                      unsigned LHSStart, unsigned RHSStart) {
-  assert(N->getValueType(0) == MVT::v16i8 &&
-         "PPC only supports shuffles by bytes!");
+  if (N->getValueType(0) != MVT::v16i8)
+    return false;
   assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
          "Unsupported merge size!");
 
@@ -910,8 +914,8 @@ bool PPC::isVMRGHShuffleMask(ShuffleVect
 /// isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift
 /// amount, otherwise return -1.
 int PPC::isVSLDOIShuffleMask(SDNode *N, bool isUnary) {
-  assert(N->getValueType(0) == MVT::v16i8 &&
-         "PPC only supports shuffles by bytes!");
+  if (N->getValueType(0) != MVT::v16i8)
+    return false;
 
   ShuffleVectorSDNode *SVOp = cast<ShuffleVectorSDNode>(N);
 

Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrVSX.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrVSX.td?rev=204873&r1=204872&r2=204873&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstrVSX.td (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstrVSX.td Wed Mar 26 17:58:37 2014
@@ -53,7 +53,6 @@ let Uses = [RM] in {
     def LXVDSX : XForm_1<31, 332,
                          (outs vsrc:$XT), (ins memrr:$src),
                          "lxvdsx $XT, $src", IIC_LdStLFD, []>;
-    // TODO: match load + splat to lxvdsx.
 
     def LXVW4X : XForm_1<31, 780,
                          (outs vsrc:$XT), (ins memrr:$src),

Modified: llvm/trunk/test/CodeGen/PowerPC/vsx.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/vsx.ll?rev=204873&r1=204872&r2=204873&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/vsx.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/vsx.ll Wed Mar 26 17:58:37 2014
@@ -422,3 +422,68 @@ define <2 x i64> @test47(<2 x float> %a)
 ; CHECK: blr
 }
 
+define <2 x double> @test50(double* %a) {
+  %v = load double* %a, align 8
+  %w = insertelement <2 x double> undef, double %v, i32 0
+  %x = insertelement <2 x double> %w, double %v, i32 1
+  ret <2 x double> %x
+
+; CHECK-LABEL: @test50
+; CHECK: lxvdsx 34, 0, 3
+; CHECK: blr
+}
+
+define <2 x double> @test51(<2 x double> %a, <2 x double> %b) {
+  %v = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 0, i32 0>
+  ret <2 x double> %v
+
+; CHECK-LABEL: @test51
+; CHECK: xxpermdi 34, 34, 34, 0
+; CHECK: blr
+}
+
+define <2 x double> @test52(<2 x double> %a, <2 x double> %b) {
+  %v = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 0, i32 2>
+  ret <2 x double> %v
+
+; CHECK-LABEL: @test52
+; CHECK: xxpermdi 34, 34, 35, 0
+; CHECK: blr
+}
+
+define <2 x double> @test53(<2 x double> %a, <2 x double> %b) {
+  %v = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 2, i32 0>
+  ret <2 x double> %v
+
+; CHECK-LABEL: @test53
+; CHECK: xxpermdi 34, 35, 34, 0
+; CHECK: blr
+}
+
+define <2 x double> @test54(<2 x double> %a, <2 x double> %b) {
+  %v = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 1, i32 2>
+  ret <2 x double> %v
+
+; CHECK-LABEL: @test54
+; CHECK: xxpermdi 34, 34, 35, 1
+; CHECK: blr
+}
+
+define <2 x double> @test55(<2 x double> %a, <2 x double> %b) {
+  %v = shufflevector <2 x double> %a, <2 x double> %b, <2 x i32> <i32 1, i32 3>
+  ret <2 x double> %v
+
+; CHECK-LABEL: @test55
+; CHECK: xxpermdi 34, 34, 35, 3
+; CHECK: blr
+}
+
+define <2 x i64> @test56(<2 x i64> %a, <2 x i64> %b) {
+  %v = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 3>
+  ret <2 x i64> %v
+
+; CHECK-LABEL: @test56
+; CHECK: xxpermdi 34, 34, 35, 3
+; CHECK: blr
+}
+





More information about the llvm-commits mailing list