[PowerPC] Lower VSELECT using xxsel when VSX is available
authorHal Finkel <hfinkel@anl.gov>
Wed, 26 Mar 2014 12:49:28 +0000 (12:49 +0000)
committerHal Finkel <hfinkel@anl.gov>
Wed, 26 Mar 2014 12:49:28 +0000 (12:49 +0000)
With VSX there is a real vector select instruction, and so we should use it.
Note that VSELECT will still scalarize for v2f64 because the corresponding
SetCC result type (v2i64) is not currently a legal type.

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

lib/Target/PowerPC/PPCISelDAGToDAG.cpp
lib/Target/PowerPC/PPCISelLowering.cpp
test/CodeGen/PowerPC/vsx.ll

index 5b09588e0f9dbedb40ca084f54ace550c12386ef..c3f36756f6f1929da309d8c14b1ac3182625dd40 100644 (file)
@@ -831,7 +831,9 @@ SDNode *PPCDAGToDAGISel::SelectSETCC(SDNode *N) {
       case ISD::SETONE:
       case ISD::SETUNE: {
         SDValue VCmp(CurDAG->getMachineNode(VCmpInst, dl, VecVT, LHS, RHS), 0);
-        return CurDAG->SelectNodeTo(N, PPC::VNOR, VecVT, VCmp, VCmp);
+        return CurDAG->SelectNodeTo(N, PPCSubTarget.hasVSX() ? PPC::XXLNOR :
+                                                               PPC::VNOR,
+                                    VecVT, VCmp, VCmp);
       } 
       case ISD::SETLT:
       case ISD::SETOLT:
@@ -853,7 +855,9 @@ SDNode *PPCDAGToDAGISel::SelectSETCC(SDNode *N) {
           SDValue VCmpGT(CurDAG->getMachineNode(VCmpInst, dl, VecVT, LHS, RHS), 0);
           unsigned int VCmpEQInst = getVCmpEQInst(VT, PPCSubTarget.hasVSX());
           SDValue VCmpEQ(CurDAG->getMachineNode(VCmpEQInst, dl, VecVT, LHS, RHS), 0);
-          return CurDAG->SelectNodeTo(N, PPC::VOR, VecVT, VCmpGT, VCmpEQ);
+          return CurDAG->SelectNodeTo(N, PPCSubTarget.hasVSX() ? PPC::XXLOR :
+                                                                 PPC::VOR,
+                                      VecVT, VCmpGT, VCmpEQ);
         }
       }
       case ISD::SETLE:
@@ -862,7 +866,9 @@ SDNode *PPCDAGToDAGISel::SelectSETCC(SDNode *N) {
         SDValue VCmpLE(CurDAG->getMachineNode(VCmpInst, dl, VecVT, RHS, LHS), 0);
         unsigned int VCmpEQInst = getVCmpEQInst(VT, PPCSubTarget.hasVSX());
         SDValue VCmpEQ(CurDAG->getMachineNode(VCmpEQInst, dl, VecVT, LHS, RHS), 0);
-        return CurDAG->SelectNodeTo(N, PPC::VOR, VecVT, VCmpLE, VCmpEQ);
+        return CurDAG->SelectNodeTo(N, PPCSubTarget.hasVSX() ? PPC::XXLOR :
+                                                               PPC::VOR,
+                                    VecVT, VCmpLE, VCmpEQ);
       }
       default:
         llvm_unreachable("Invalid vector compare type: should be expanded by legalize");
@@ -1323,6 +1329,13 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
                         getI32Imm(BROpc) };
     return CurDAG->SelectNodeTo(N, SelectCCOp, N->getValueType(0), Ops, 4);
   }
+  case ISD::VSELECT:
+    if (PPCSubTarget.hasVSX()) {
+      SDValue Ops[] = { N->getOperand(2), N->getOperand(1), N->getOperand(0) };
+      return CurDAG->SelectNodeTo(N, PPC::XXSEL, N->getValueType(0), Ops, 3);
+    }
+
+    break;
   case PPCISD::BDNZ:
   case PPCISD::BDZ: {
     bool IsPPC64 = PPCSubTarget.isPPC64();
index a35c83c19d52bf6b7a59fc42f48e7b62ed090ff9..2cc8f469548793260d2b491e81469a24f2c20905 100644 (file)
@@ -550,6 +550,12 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM)
       setOperationAction(ISD::FDIV, MVT::v2f64, Legal);
       setOperationAction(ISD::FSQRT, MVT::v2f64, Legal);
 
+      setOperationAction(ISD::VSELECT, MVT::v16i8, Legal);
+      setOperationAction(ISD::VSELECT, MVT::v8i16, Legal);
+      setOperationAction(ISD::VSELECT, MVT::v4i32, Legal);
+      setOperationAction(ISD::VSELECT, MVT::v4f32, Legal);
+      setOperationAction(ISD::VSELECT, MVT::v2f64, Legal);
+
       // Share the Altivec comparison restrictions.
       setCondCodeAction(ISD::SETUO, MVT::v2f64, Expand);
       setCondCodeAction(ISD::SETUEQ, MVT::v2f64, Expand);
index 5455565ce3db3f812da6e81423f37e53f76fbb6b..b94c80c05f34a4a0d7f04abc57f936057bb6cd86 100644 (file)
@@ -198,3 +198,80 @@ entry:
 ; CHECK: blr
 }
 
+define <4 x i32> @test20(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c, <4 x i32> %d) {
+entry:
+  %m = icmp eq <4 x i32> %c, %d
+  %v = select <4 x i1> %m, <4 x i32> %a, <4 x i32> %b
+  ret <4 x i32> %v
+
+; CHECK-LABEL: @test20
+; CHECK: vcmpequw {{[0-9]+}}, 4, 5
+; CHECK: xxsel 34, 35, 34, {{[0-9]+}}
+; CHECK: blr
+}
+
+define <4 x float> @test21(<4 x float> %a, <4 x float> %b, <4 x float> %c, <4 x float> %d) {
+entry:
+  %m = fcmp oeq <4 x float> %c, %d
+  %v = select <4 x i1> %m, <4 x float> %a, <4 x float> %b
+  ret <4 x float> %v
+
+; CHECK-LABEL: @test21
+; CHECK: xvcmpeqsp [[V1:[0-9]+]], 36, 37
+; CHECK: xxsel 34, 35, 34, [[V1]]
+; CHECK: blr
+}
+
+define <4 x float> @test22(<4 x float> %a, <4 x float> %b, <4 x float> %c, <4 x float> %d) {
+entry:
+  %m = fcmp ueq <4 x float> %c, %d
+  %v = select <4 x i1> %m, <4 x float> %a, <4 x float> %b
+  ret <4 x float> %v
+
+; CHECK-LABEL: @test22
+; CHECK-DAG: xvcmpeqsp {{[0-9]+}}, 37, 37
+; CHECK-DAG: xvcmpeqsp {{[0-9]+}}, 36, 36
+; CHECK-DAG: xvcmpeqsp {{[0-9]+}}, 36, 37
+; CHECK-DAG: xxlnor
+; CHECK-DAG: xxlnor
+; CHECK-DAG: xxlor
+; CHECK-DAG: xxlor
+; CHECK: xxsel 34, 35, 34, {{[0-9]+}}
+; CHECK: blr
+}
+
+define <8 x i16> @test23(<8 x i16> %a, <8 x i16> %b, <8 x i16> %c, <8 x i16> %d) {
+entry:
+  %m = icmp eq <8 x i16> %c, %d
+  %v = select <8 x i1> %m, <8 x i16> %a, <8 x i16> %b
+  ret <8 x i16> %v
+
+; CHECK-LABEL: @test23
+; CHECK: vcmpequh {{[0-9]+}}, 4, 5
+; CHECK: xxsel 34, 35, 34, {{[0-9]+}}
+; CHECK: blr
+}
+
+define <16 x i8> @test24(<16 x i8> %a, <16 x i8> %b, <16 x i8> %c, <16 x i8> %d) {
+entry:
+  %m = icmp eq <16 x i8> %c, %d
+  %v = select <16 x i1> %m, <16 x i8> %a, <16 x i8> %b
+  ret <16 x i8> %v
+
+; CHECK-LABEL: @test24
+; CHECK: vcmpequb {{[0-9]+}}, 4, 5
+; CHECK: xxsel 34, 35, 34, {{[0-9]+}}
+; CHECK: blr
+}
+
+define <2 x double> @test25(<2 x double> %a, <2 x double> %b, <2 x double> %c, <2 x double> %d) {
+entry:
+  %m = fcmp oeq <2 x double> %c, %d
+  %v = select <2 x i1> %m, <2 x double> %a, <2 x double> %b
+  ret <2 x double> %v
+
+; CHECK-LABEL: @test25
+; FIXME: This currently is scalarized because v2i64 is not a legal type.
+; CHECK: blr
+}
+