summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelLowering.cpp23
-rw-r--r--llvm/test/CodeGen/PowerPC/vsx.ll33
2 files changed, 56 insertions, 0 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 527430238cb..27362d7f5c9 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/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<CondCodeSDNode>(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/llvm/test/CodeGen/PowerPC/vsx.ll b/llvm/test/CodeGen/PowerPC/vsx.ll
index ec10bc683b0..f3e325f322b 100644
--- a/llvm/test/CodeGen/PowerPC/vsx.ll
+++ b/llvm/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
+}
+
OpenPOWER on IntegriCloud