diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 527430238cb..27362d7f5c9 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -586,6 +586,8 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM) setOperationAction(ISD::SRA, MVT::v2i64, Expand); setOperationAction(ISD::SRL, MVT::v2i64, Expand); + setOperationAction(ISD::SETCC, MVT::v2i64, Custom); + setOperationAction(ISD::LOAD, MVT::v2i64, Promote); AddPromotedToType (ISD::LOAD, MVT::v2i64, MVT::v2f64); setOperationAction(ISD::STORE, MVT::v2i64, Promote); @@ -1662,6 +1664,27 @@ SDValue PPCTargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const { ISD::CondCode CC = cast(Op.getOperand(2))->get(); SDLoc dl(Op); + if (Op.getValueType() == MVT::v2i64) { + // When the operands themselves are v2i64 values, we need to do something + // special because VSX has no underlying comparison operations for these. + if (Op.getOperand(0).getValueType() == MVT::v2i64) { + // Equality can be handled by casting to the legal type for Altivec + // comparisons, everything else needs to be expanded. + if (CC == ISD::SETEQ || CC == ISD::SETNE) { + return DAG.getNode(ISD::BITCAST, dl, MVT::v2i64, + DAG.getSetCC(dl, MVT::v4i32, + DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, Op.getOperand(0)), + DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, Op.getOperand(1)), + CC)); + } + + return SDValue(); + } + + // We handle most of these in the usual way. + return Op; + } + // If we're comparing for equality to zero, expose the fact that this is // implented as a ctlz/srl pair on ppc, so that the dag combiner can // fold the new nodes. diff --git a/test/CodeGen/PowerPC/vsx.ll b/test/CodeGen/PowerPC/vsx.ll index ec10bc683b0..f3e325f322b 100644 --- a/test/CodeGen/PowerPC/vsx.ll +++ b/test/CodeGen/PowerPC/vsx.ll @@ -547,3 +547,36 @@ define double @test64(<2 x double> %a) { ; CHECK: blr } +define <2 x i1> @test65(<2 x i64> %a, <2 x i64> %b) { + %w = icmp eq <2 x i64> %a, %b + ret <2 x i1> %w + +; CHECK-LABEL: @test65 +; CHECK: vcmpequw 2, 2, 3 +; CHECK: blr +} + +define <2 x i1> @test66(<2 x i64> %a, <2 x i64> %b) { + %w = icmp ne <2 x i64> %a, %b + ret <2 x i1> %w + +; CHECK-LABEL: @test66 +; CHECK: vcmpequw {{[0-9]+}}, 2, 3 +; CHECK: xxlnor 34, {{[0-9]+}}, {{[0-9]+}} +; CHECK: blr +} + +define <2 x i1> @test67(<2 x i64> %a, <2 x i64> %b) { + %w = icmp ult <2 x i64> %a, %b + ret <2 x i1> %w + +; CHECK-LABEL: @test67 +; This should scalarize, and the current code quality is not good. +; CHECK: stxvd2x +; CHECK: stxvd2x +; CHECK: cmpld +; CHECK: cmpld +; CHECK: lxvd2x +; CHECK: blr +} +