diff --git a/include/llvm/IR/IntrinsicsPowerPC.td b/include/llvm/IR/IntrinsicsPowerPC.td index f2655d403c9..99fd1973b82 100644 --- a/include/llvm/IR/IntrinsicsPowerPC.td +++ b/include/llvm/IR/IntrinsicsPowerPC.td @@ -361,6 +361,16 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.". Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>; + def int_ppc_altivec_vcmpequq : GCCBuiltin<"__builtin_altivec_vcmpequq">, + Intrinsic<[llvm_v1i128_ty], [llvm_v1i128_ty, llvm_v1i128_ty], + [IntrNoMem]>; + def int_ppc_altivec_vcmpgtsq : GCCBuiltin<"__builtin_altivec_vcmpgtsq">, + Intrinsic<[llvm_v1i128_ty], [llvm_v1i128_ty, llvm_v1i128_ty], + [IntrNoMem]>; + def int_ppc_altivec_vcmpgtuq : GCCBuiltin<"__builtin_altivec_vcmpgtuq">, + Intrinsic<[llvm_v1i128_ty], [llvm_v1i128_ty, llvm_v1i128_ty], + [IntrNoMem]>; + // Predicate Comparisons. The first operand specifies interpretation of CR6. def int_ppc_altivec_vcmpbfp_p : GCCBuiltin<"__builtin_altivec_vcmpbfp_p">, Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4f32_ty,llvm_v4f32_ty], diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index 2da9f455acd..5fa62fbda4b 100644 --- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -3948,7 +3948,8 @@ static unsigned getCRIdxForSetCC(ISD::CondCode CC, bool &Invert) { // getVCmpInst: return the vector compare instruction for the specified // vector type and condition code. Since this is for altivec specific code, -// only support the altivec types (v16i8, v8i16, v4i32, v2i64, and v4f32). +// only support the altivec types (v16i8, v8i16, v4i32, v2i64, v1i128, +// and v4f32). static unsigned int getVCmpInst(MVT VecVT, ISD::CondCode CC, bool HasVSX, bool &Swap, bool &Negate) { Swap = false; @@ -4029,6 +4030,8 @@ static unsigned int getVCmpInst(MVT VecVT, ISD::CondCode CC, return PPC::VCMPEQUW; else if (VecVT == MVT::v2i64) return PPC::VCMPEQUD; + else if (VecVT == MVT::v1i128) + return PPC::VCMPEQUQ; break; case ISD::SETGT: if (VecVT == MVT::v16i8) @@ -4039,6 +4042,8 @@ static unsigned int getVCmpInst(MVT VecVT, ISD::CondCode CC, return PPC::VCMPGTSW; else if (VecVT == MVT::v2i64) return PPC::VCMPGTSD; + else if (VecVT == MVT::v1i128) + return PPC::VCMPGTSQ; break; case ISD::SETUGT: if (VecVT == MVT::v16i8) @@ -4049,6 +4054,8 @@ static unsigned int getVCmpInst(MVT VecVT, ISD::CondCode CC, return PPC::VCMPGTUW; else if (VecVT == MVT::v2i64) return PPC::VCMPGTUD; + else if (VecVT == MVT::v1i128) + return PPC::VCMPGTUQ; break; default: break; diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 7be24fd1e90..5a75d229e0d 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -1005,7 +1005,10 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM, setOperationAction(ISD::SUB, MVT::v2i64, Expand); } - setOperationAction(ISD::SETCC, MVT::v1i128, Expand); + if (Subtarget.isISA3_1()) + setOperationAction(ISD::SETCC, MVT::v1i128, Legal); + else + setOperationAction(ISD::SETCC, MVT::v1i128, Expand); setOperationAction(ISD::LOAD, MVT::v2i64, Promote); AddPromotedToType (ISD::LOAD, MVT::v2i64, MVT::v2f64); @@ -10212,6 +10215,26 @@ static bool getVectorCompareInfo(SDValue Intrin, int &CompareOpc, return false; break; + case Intrinsic::ppc_altivec_vcmpequq: + case Intrinsic::ppc_altivec_vcmpgtsq: + case Intrinsic::ppc_altivec_vcmpgtuq: + if (!Subtarget.isISA3_1()) + return false; + switch (IntrinsicID) { + default: + llvm_unreachable("Unknown comparison intrinsic."); + case Intrinsic::ppc_altivec_vcmpequq: + CompareOpc = 455; + break; + case Intrinsic::ppc_altivec_vcmpgtsq: + CompareOpc = 903; + break; + case Intrinsic::ppc_altivec_vcmpgtuq: + CompareOpc = 647; + break; + } + break; + // VSX predicate comparisons use the same infrastructure case Intrinsic::ppc_vsx_xvcmpeqdp_p: case Intrinsic::ppc_vsx_xvcmpgedp_p: diff --git a/test/CodeGen/PowerPC/vec_cmpq.ll b/test/CodeGen/PowerPC/vec_cmpq.ll new file mode 100644 index 00000000000..6cddf7cee79 --- /dev/null +++ b/test/CodeGen/PowerPC/vec_cmpq.ll @@ -0,0 +1,250 @@ +; Test the quadword comparison instructions that were added in POWER10. +; +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \ +; RUN: -mcpu=pwr10 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \ +; RUN: -mcpu=pwr10 -mattr=-vsx < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \ +; RUN: -mcpu=pwr10 < %s | FileCheck %s +define <1 x i128> @v1si128_cmp(<1 x i128> %x, <1 x i128> %y) nounwind readnone { + %cmp = icmp eq <1 x i128> %x, %y + %result = sext <1 x i1> %cmp to <1 x i128> + ret <1 x i128> %result +; CHECK-LABEL: v1si128_cmp: +; CHECK: vcmpequq 2, 2, 3 +} + +define <2 x i128> @v2si128_cmp(<2 x i128> %x, <2 x i128> %y) nounwind readnone { + %cmp = icmp eq <2 x i128> %x, %y + %result = sext <2 x i1> %cmp to <2 x i128> + ret <2 x i128> %result +; CHECK-LABEL: v2si128_cmp +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: blr +} + +define <4 x i128> @v4si128_cmp(<4 x i128> %x, <4 x i128> %y) nounwind readnone { + %cmp = icmp eq <4 x i128> %x, %y + %result = sext <4 x i1> %cmp to <4 x i128> + ret <4 x i128> %result +; CHECK-LABEL: v4si128_cmp +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: blr +} + +define <8 x i128> @v8si128_cmp(<8 x i128> %x, <8 x i128> %y) nounwind readnone { + %cmp = icmp eq <8 x i128> %x, %y + %result = sext <8 x i1> %cmp to <8 x i128> + ret <8 x i128> %result +; CHECK-LABEL: v8si128_cmp +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: blr +} + +define <16 x i128> @v16si128_cmp(<16 x i128> %x, <16 x i128> %y) nounwind readnone { + %cmp = icmp eq <16 x i128> %x, %y + %result = sext <16 x i1> %cmp to <16 x i128> + ret <16 x i128> %result +; CHECK-LABEL: v16si128_cmp +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: blr +} + +; Greater than signed +define <1 x i128> @v1si128_cmp_gt(<1 x i128> %x, <1 x i128> %y) nounwind readnone { + %cmp = icmp sgt <1 x i128> %x, %y + %result = sext <1 x i1> %cmp to <1 x i128> + ret <1 x i128> %result +; CHECK-LABEL: v1si128_cmp_gt +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: blr +} + +define <2 x i128> @v2si128_cmp_gt(<2 x i128> %x, <2 x i128> %y) nounwind readnone { + %cmp = icmp sgt <2 x i128> %x, %y + %result = sext <2 x i1> %cmp to <2 x i128> + ret <2 x i128> %result +; CHECK-LABEL: v2si128_cmp_gt +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: blr +} + +define <4 x i128> @v4si128_cmp_gt(<4 x i128> %x, <4 x i128> %y) nounwind readnone { + %cmp = icmp sgt <4 x i128> %x, %y + %result = sext <4 x i1> %cmp to <4 x i128> + ret <4 x i128> %result +; CHECK-LABEL: v4si128_cmp_gt +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: blr +} + +define <8 x i128> @v8si128_cmp_gt(<8 x i128> %x, <8 x i128> %y) nounwind readnone { + %cmp = icmp sgt <8 x i128> %x, %y + %result = sext <8 x i1> %cmp to <8 x i128> + ret <8 x i128> %result +; CHECK-LABEL: v8si128_cmp_gt +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: blr +} + +define <16 x i128> @v16si128_cmp_gt(<16 x i128> %x, <16 x i128> %y) nounwind readnone { + %cmp = icmp sgt <16 x i128> %x, %y + %result = sext <16 x i1> %cmp to <16 x i128> + ret <16 x i128> %result +; CHECK-LABEL: v16si128_cmp_gt +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: blr +} + +; Greater than unsigned +define <1 x i128> @v1ui128_cmp_gt(<1 x i128> %x, <1 x i128> %y) nounwind readnone { + %cmp = icmp ugt <1 x i128> %x, %y + %result = sext <1 x i1> %cmp to <1 x i128> + ret <1 x i128> %result +; CHECK-LABEL: v1ui128_cmp_gt +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: blr +} + +define <2 x i128> @v2ui128_cmp_gt(<2 x i128> %x, <2 x i128> %y) nounwind readnone { + %cmp = icmp ugt <2 x i128> %x, %y + %result = sext <2 x i1> %cmp to <2 x i128> + ret <2 x i128> %result +; CHECK-LABEL: v2ui128_cmp_gt +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: blr +} + +define <4 x i128> @v4ui128_cmp_gt(<4 x i128> %x, <4 x i128> %y) nounwind readnone { + %cmp = icmp ugt <4 x i128> %x, %y + %result = sext <4 x i1> %cmp to <4 x i128> + ret <4 x i128> %result +; CHECK-LABEL: v4ui128_cmp_gt +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: blr +} + +define <8 x i128> @v8ui128_cmp_gt(<8 x i128> %x, <8 x i128> %y) nounwind readnone { + %cmp = icmp ugt <8 x i128> %x, %y + %result = sext <8 x i1> %cmp to <8 x i128> + ret <8 x i128> %result +; CHECK-LABEL: v8ui128_cmp_gt +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: blr +} + +define <16 x i128> @v16ui128_cmp_gt(<16 x i128> %x, <16 x i128> %y) nounwind readnone { + %cmp = icmp ugt <16 x i128> %x, %y + %result = sext <16 x i1> %cmp to <16 x i128> + ret <16 x i128> %result +; CHECK-LABEL: v16ui128_cmp_gt +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: blr +} + +; Check the intrinsics also +declare <1 x i128> @llvm.ppc.altivec.vcmpequq(<1 x i128>, <1 x i128>) nounwind readnone +declare <1 x i128> @llvm.ppc.altivec.vcmpgtsq(<1 x i128>, <1 x i128>) nounwind readnone +declare <1 x i128> @llvm.ppc.altivec.vcmpgtuq(<1 x i128>, <1 x i128>) nounwind readnone + +define <1 x i128> @test_vcmpequq(<1 x i128> %x, <1 x i128> %y) { + %tmp = tail call <1 x i128> @llvm.ppc.altivec.vcmpequq(<1 x i128> %x, <1 x i128> %y) + ret <1 x i128> %tmp +; CHECK-LABEL: test_vcmpequq: +; CHECK: vcmpequq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: blr +} + +define <1 x i128> @test_vcmpgtsq(<1 x i128> %x, <1 x i128> %y) { + %tmp = tail call <1 x i128> @llvm.ppc.altivec.vcmpgtsq(<1 x i128> %x, <1 x i128> %y) + ret <1 x i128> %tmp +; CHECK-LABEL: test_vcmpgtsq +; CHECK: vcmpgtsq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: blr +} + +define <1 x i128> @test_vcmpgtuq(<1 x i128> %x, <1 x i128> %y) { + %tmp = tail call <1 x i128> @llvm.ppc.altivec.vcmpgtuq(<1 x i128> %x, <1 x i128> %y) + ret <1 x i128> %tmp +; CHECK-LABEL: test_vcmpgtuq +; CHECK: vcmpgtuq {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} +; CHECK: blr +}