diff options
author | Hal Finkel <hfinkel@anl.gov> | 2014-03-26 12:49:28 +0000 |
---|---|---|
committer | Hal Finkel <hfinkel@anl.gov> | 2014-03-26 12:49:28 +0000 |
commit | 159e7f40956437a2513f54e19b03772bd3a0e942 (patch) | |
tree | bd9638332c9c00f3141f1bccad79a72718b4360a | |
parent | 23f06341623172c666b4cb56f04cf65194d33ef9 (diff) |
[PowerPC] Lower VSELECT using xxsel when VSX is available
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
-rw-r--r-- | lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 19 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCISelLowering.cpp | 6 | ||||
-rw-r--r-- | test/CodeGen/PowerPC/vsx.ll | 77 |
3 files changed, 99 insertions, 3 deletions
diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index 5b09588e0f9..c3f36756f6f 100644 --- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -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(); diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index a35c83c19d5..2cc8f469548 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -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); diff --git a/test/CodeGen/PowerPC/vsx.ll b/test/CodeGen/PowerPC/vsx.ll index 5455565ce3d..b94c80c05f3 100644 --- a/test/CodeGen/PowerPC/vsx.ll +++ b/test/CodeGen/PowerPC/vsx.ll @@ -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 +} + |