1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00

[PowerPC] Implement Vector signed/unsigned __int128 overloads for the comparison builtins

This patch implements Vector signed/unsigned __int128 overloads for the comparison builtins.

Differential Revision: https://reviews.llvm.org/D87804
This commit is contained in:
Albion Fung 2020-09-23 16:37:48 -04:00
parent a8a8abc4ed
commit 3a1a7e4141
4 changed files with 292 additions and 2 deletions

View File

@ -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],

View File

@ -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;

View File

@ -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:

View File

@ -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
}