[PowerPC] Handle v2i64 comparisons
authorHal Finkel <hfinkel@anl.gov>
Sat, 29 Mar 2014 16:04:40 +0000 (16:04 +0000)
committerHal Finkel <hfinkel@anl.gov>
Sat, 29 Mar 2014 16:04:40 +0000 (16:04 +0000)
v2i64 is a legal type under VSX, however we don't have native vector
comparisons. We can handle eq/ne by casting it to an Altivec type, but
everything else must be expanded.

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

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

index 527430238cba00da673080fddc8589fa0fa204bb..27362d7f5c9ce75f61eac6d898a52148e1860f5a 100644 (file)
@@ -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.
index ec10bc683b01797cfb7b18f9e5a3a88dc852374f..f3e325f322b6fe87dfa592cd0a530d16ff4c0bd8 100644 (file)
@@ -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
+}
+