258 changes: 258 additions & 0 deletions clang/test/CodeGen/builtins-ppc-p10vector.c
Original file line number Diff line number Diff line change
Expand Up @@ -1499,3 +1499,261 @@ vector signed __int128 test_vec_mod_s128(void) {
// CHECK-NEXT: ret <1 x i128>
return vec_mod(vsi128a, vsi128b);
}

vector bool __int128 test_vec_cmpeq_s128(void) {
// CHECK-LABEL: @test_vec_cmpeq_s128(
// CHECK: call <1 x i128> @llvm.ppc.altivec.vcmpequq(<1 x i128>
// CHECK-NEXT: ret <1 x i128>
return vec_cmpeq(vsi128a, vsi128b);
}

vector bool __int128 test_vec_cmpeq_u128(void) {
// CHECK-LABEL: @test_vec_cmpeq_u128(
// CHECK: call <1 x i128> @llvm.ppc.altivec.vcmpequq(<1 x i128>
// CHECK-NEXT: ret <1 x i128>
return vec_cmpeq(vui128a, vui128b);
}

vector bool __int128 test_vec_cmpne_s128(void) {
// CHECK-LABEL: @test_vec_cmpne_s128(
// CHECK: call <1 x i128> @llvm.ppc.altivec.vcmpequq(<1 x i128>
// CHECK-NEXT: %neg.i = xor <1 x i128> %4, <i128 -1>
// CHECK-NEXT: ret <1 x i128> %neg.i
return vec_cmpne(vsi128a, vsi128b);
}

vector bool __int128 test_vec_cmpne_u128(void) {
// CHECK-LABEL: @test_vec_cmpne_u128(
// CHECK: call <1 x i128> @llvm.ppc.altivec.vcmpequq(<1 x i128>
// CHECK-NEXT: %neg.i = xor <1 x i128> %4, <i128 -1>
// CHECK-NEXT: ret <1 x i128>
return vec_cmpne(vui128a, vui128b);
}

vector bool __int128 test_vec_cmpgt_s128(void) {
// CHECK-LABEL: @test_vec_cmpgt_s128(
// CHECK: call <1 x i128> @llvm.ppc.altivec.vcmpgtsq(<1 x i128>
// CHECK-NEXT: ret <1 x i128>
return vec_cmpgt(vsi128a, vsi128b);
}

vector bool __int128 test_vec_cmpgt_u128(void) {
// CHECK-LABEL: @test_vec_cmpgt_u128(
// CHECK: call <1 x i128> @llvm.ppc.altivec.vcmpgtuq(<1 x i128>
// CHECK-NEXT: ret <1 x i128>
return vec_cmpgt(vui128a, vui128b);
}

vector bool __int128 test_vec_cmplt_s128(void) {
// CHECK-LABEL: @test_vec_cmplt_s128(
// CHECK: call <1 x i128> @llvm.ppc.altivec.vcmpgtsq(<1 x i128>
// CHECK-NEXT: ret <1 x i128>
return vec_cmplt(vsi128a, vsi128b);
}

vector bool __int128 test_vec_cmplt_u128(void) {
// CHECK-LABEL: @test_vec_cmplt_u128(
// CHECK: call <1 x i128> @llvm.ppc.altivec.vcmpgtuq(<1 x i128>
// CHECK-NEXT: ret <1 x i128>
return vec_cmplt(vui128a, vui128b);
}

vector bool __int128 test_vec_cmpge_s128(void) {
// CHECK-LABEL: @test_vec_cmpge_s128(
// CHECK: call <1 x i128> @llvm.ppc.altivec.vcmpgtsq(<1 x i128>
// CHECK-NEXT: %neg.i = xor <1 x i128> %6, <i128 -1>
// CHECK-NEXT: ret <1 x i128>
return vec_cmpge(vsi128a, vsi128b);
}

vector bool __int128 test_vec_cmpge_u128(void) {
// CHECK-LABEL: @test_vec_cmpge_u128(
// CHECK: call <1 x i128> @llvm.ppc.altivec.vcmpgtuq(<1 x i128>
// CHECK-NEXT: %neg.i = xor <1 x i128> %6, <i128 -1>
// CHECK-NEXT: ret <1 x i128>
return vec_cmpge(vui128a, vui128b);
}

vector bool __int128 test_vec_cmple_s128(void) {
// CHECK-LABEL: @test_vec_cmple_s128(
// CHECK: call <1 x i128> @llvm.ppc.altivec.vcmpgtsq(<1 x i128>
// CHECK-NEXT: %neg.i.i = xor <1 x i128> %8, <i128 -1>
// CHECK-NEXT: ret <1 x i128>
return vec_cmple(vsi128a, vsi128b);
}

vector bool __int128 test_vec_cmple_u128(void) {
// CHECK-LABEL: @test_vec_cmple_u128(
// CHECK: call <1 x i128> @llvm.ppc.altivec.vcmpgtuq(<1 x i128>
// CHECK-NEXT: %neg.i.i = xor <1 x i128> %8, <i128 -1>
// CHECK-NEXT: ret <1 x i128>
return vec_cmple(vui128a, vui128b);
}

int test_vec_any_eq_u128(void) {
// CHECK-LABEL: @test_vec_any_eq_u128(
// CHECK: call i32 @llvm.ppc.altivec.vcmpequq.p(i32 1, <1 x i128> %2, <1 x i128> %3)
// CHECK-NEXT: ret i32
return vec_any_eq(vui128a, vui128b);
}

int test_vec_any_eq_s128(void) {
// CHECK-LABEL: @test_vec_any_eq_s128(
// CHECK: call i32 @llvm.ppc.altivec.vcmpequq.p(i32 1, <1 x i128> %2, <1 x i128> %3)
// CHECK-NEXT: ret i32
return vec_any_eq(vsi128a, vsi128b);
}

int test_vec_any_ne_s128(void) {
// CHECK-LABEL: @test_vec_any_ne_s128(
// CHECK: call i32 @llvm.ppc.altivec.vcmpequq.p(i32 3, <1 x i128> %2, <1 x i128> %3)
// CHECK-NEXT: ret i32
return vec_any_ne(vsi128a, vsi128b);
}

int test_vec_any_ne_u128(void) {
// CHECK-LABEL: @test_vec_any_ne_u128(
// CHECK: call i32 @llvm.ppc.altivec.vcmpequq.p(i32 3, <1 x i128> %2, <1 x i128> %3)
// CHECK-NEXT: ret i32
return vec_any_ne(vui128a, vui128b);
}

int test_vec_any_lt_s128(void) {
// CHECK-LABEL: @test_vec_any_lt_s128(
// CHECK: call i32 @llvm.ppc.altivec.vcmpgtsq.p(i32 1, <1 x i128> %2, <1 x i128> %3)
// CHECK-NEXT: ret i32
return vec_any_lt(vsi128a, vsi128b);
}

int test_vec_any_lt_u128(void) {
// CHECK-LABEL: @test_vec_any_lt_u128(
// CHECK: call i32 @llvm.ppc.altivec.vcmpgtuq.p(i32 1, <1 x i128> %2, <1 x i128> %3)
// CHECK-NEXT: ret i32
return vec_any_lt(vui128a, vui128b);
}

int test_vec_any_gt_s128(void) {
// CHECK-LABEL: @test_vec_any_gt_s128(
// CHECK: call i32 @llvm.ppc.altivec.vcmpgtsq.p(i32 1, <1 x i128> %2, <1 x i128> %3)
// CHECK-NEXT: ret i32
return vec_any_gt(vsi128a, vsi128b);
}

int test_vec_any_gt_u128(void) {
// CHECK-LABEL: @test_vec_any_gt_u128(
// CHECK: call i32 @llvm.ppc.altivec.vcmpgtuq.p(i32 1, <1 x i128> %2, <1 x i128> %3)
// CHECK-NEXT: ret i32
return vec_any_gt(vui128a, vui128b);
}

int test_vec_any_le_s128(void) {
// CHECK-LABEL: @test_vec_any_le_s128(
// CHECK: call i32 @llvm.ppc.altivec.vcmpgtsq.p(i32 3, <1 x i128> %2, <1 x i128> %3)
// CHECK-NEXT: ret i32
return vec_any_le(vsi128a, vsi128b);
}

int test_vec_any_le_u128(void) {
// CHECK-LABEL: @test_vec_any_le_u128(
// CHECK: call i32 @llvm.ppc.altivec.vcmpgtuq.p(i32 3, <1 x i128> %2, <1 x i128> %3)
// CHECK-NEXT: ret i32
return vec_any_le(vui128a, vui128b);
}

int test_vec_any_ge_s128(void) {
// CHECK-LABEL: @test_vec_any_ge_s128(
// CHECK: call i32 @llvm.ppc.altivec.vcmpgtsq.p(i32 3, <1 x i128> %2, <1 x i128> %3)
// CHECK-NEXT: ret i32
return vec_any_ge(vsi128a, vsi128b);
}

int test_vec_any_ge_u128(void) {
// CHECK-LABEL: @test_vec_any_ge_u128(
// CHECK: call i32 @llvm.ppc.altivec.vcmpgtuq.p(i32 3, <1 x i128> %2, <1 x i128> %3)
// CHECK-NEXT: ret i32
return vec_any_ge(vui128a, vui128b);
}

int test_vec_all_eq_s128(void) {
// CHECK-LABEL: @test_vec_all_eq_s128(
// CHECK: call i32 @llvm.ppc.altivec.vcmpequq.p(i32 2, <1 x i128> %2, <1 x i128> %3)
// CHECK-NEXT: ret i32
return vec_all_eq(vsi128a, vsi128b);
}

int test_vec_all_eq_u128(void) {
// CHECK-LABEL: @test_vec_all_eq_u128(
// CHECK: call i32 @llvm.ppc.altivec.vcmpequq.p(i32 2, <1 x i128> %2, <1 x i128> %3)
// CHECK-NEXT: ret i32
return vec_all_eq(vui128a, vui128b);
}

int test_vec_all_ne_s128(void) {
// CHECK-LABEL: @test_vec_all_ne_s128(
// CHECK: call i32 @llvm.ppc.altivec.vcmpequq.p(i32 0, <1 x i128> %2, <1 x i128> %3)
// CHECK-NEXT: ret i32
return vec_all_ne(vsi128a, vsi128b);
}

int test_vec_all_ne_u128(void) {
// CHECK-LABEL: @test_vec_all_ne_u128(
// CHECK: call i32 @llvm.ppc.altivec.vcmpequq.p(i32 0, <1 x i128> %2, <1 x i128> %3)
// CHECK-NEXT: ret i32
return vec_all_ne(vui128a, vui128b);
}

int test_vec_all_lt_s128(void) {
// CHECK-LABEL: @test_vec_all_lt_s128(
// CHECK: call i32 @llvm.ppc.altivec.vcmpgtsq.p(i32 2, <1 x i128> %2, <1 x i128> %3)
// CHECK-NEXT: ret i32
return vec_all_lt(vsi128a, vsi128b);
}

int test_vec_all_lt_u128(void) {
// CHECK-LABEL: @test_vec_all_lt_u128(
// CHECK: call i32 @llvm.ppc.altivec.vcmpgtuq.p(i32 2, <1 x i128> %2, <1 x i128> %3)
// CHECK: ret i32
return vec_all_lt(vui128a, vui128b);
}

int test_vec_all_gt_s128(void) {
// CHECK-LABEL: @test_vec_all_gt_s128(
// CHECK: call i32 @llvm.ppc.altivec.vcmpgtsq.p(i32 2, <1 x i128> %2, <1 x i128> %3)
// CHECK-NEXT: ret i32
return vec_all_gt(vsi128a, vsi128b);
}

int test_vec_all_gt_u128(void) {
// CHECK-LABEL: @test_vec_all_gt_u128(
// CHECK: call i32 @llvm.ppc.altivec.vcmpgtuq.p(i32 2, <1 x i128> %2, <1 x i128> %3)
// CHECK-NEXT: ret i32
return vec_all_gt(vui128a, vui128b);
}

int test_vec_all_le_s128(void) {
// CHECK-LABEL: @test_vec_all_le_s128(
// CHECK: call i32 @llvm.ppc.altivec.vcmpgtsq.p(i32 0, <1 x i128> %2, <1 x i128> %3)
// CHECK-NEXT: ret i32
return vec_all_le(vsi128a, vsi128b);
}

int test_vec_all_le_u128(void) {
// CHECK-LABEL: @test_vec_all_le_u128(
// CHECK: call i32 @llvm.ppc.altivec.vcmpgtuq.p(i32 0, <1 x i128> %2, <1 x i128> %3)
// CHECK-NEXT: ret i32
return vec_all_le(vui128a, vui128b);
}

int test_vec_all_ge_s128(void) {
// CHECK-LABEL: @test_vec_all_ge_s128(
// CHECK: call i32 @llvm.ppc.altivec.vcmpgtsq.p(i32 0, <1 x i128> %2, <1 x i128> %3)
// CHECK-NEXT: ret i32
return vec_all_ge(vsi128a, vsi128b);
}

int test_vec_all_ge_u128(void) {
// CHECK-LABEL: @test_vec_all_ge_u128(
// CHECK: call i32 @llvm.ppc.altivec.vcmpgtuq.p(i32 0, <1 x i128> %2, <1 x i128> %3)
// CHECK-NEXT: ret i32
return vec_all_ge(vui128a, vui128b);
}
22 changes: 22 additions & 0 deletions llvm/include/llvm/IR/IntrinsicsPowerPC.td
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,28 @@ 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]>;
def int_ppc_altivec_vcmpequq_p : GCCBuiltin<"__builtin_altivec_vcmpequq_p">,
Intrinsic<[llvm_i32_ty],
[llvm_i32_ty,llvm_v1i128_ty,llvm_v1i128_ty],
[IntrNoMem]>;
def int_ppc_altivec_vcmpgtsq_p : GCCBuiltin<"__builtin_altivec_vcmpgtsq_p">,
Intrinsic<[llvm_i32_ty],
[llvm_i32_ty,llvm_v1i128_ty,llvm_v1i128_ty],
[IntrNoMem]>;
def int_ppc_altivec_vcmpgtuq_p : GCCBuiltin<"__builtin_altivec_vcmpgtuq_p">,
Intrinsic<[llvm_i32_ty],
[llvm_i32_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],
Expand Down
9 changes: 8 additions & 1 deletion llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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;
Expand Down
48 changes: 47 additions & 1 deletion llvm/lib/Target/PowerPC/PPCISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -10335,6 +10358,26 @@ static bool getVectorCompareInfo(SDValue Intrin, int &CompareOpc,
else
return false;
break;
case Intrinsic::ppc_altivec_vcmpequq_p:
case Intrinsic::ppc_altivec_vcmpgtsq_p:
case Intrinsic::ppc_altivec_vcmpgtuq_p:
if (!Subtarget.isISA3_1())
return false;
switch (IntrinsicID) {
default:
llvm_unreachable("Unknown comparison intrinsic.");
case Intrinsic::ppc_altivec_vcmpequq_p:
CompareOpc = 455;
break;
case Intrinsic::ppc_altivec_vcmpgtsq_p:
CompareOpc = 903;
break;
case Intrinsic::ppc_altivec_vcmpgtuq_p:
CompareOpc = 647;
break;
}
isDot = true;
break;
}
return true;
}
Expand Down Expand Up @@ -15201,16 +15244,19 @@ void PPCTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
case Intrinsic::ppc_altivec_vcmpequh_p:
case Intrinsic::ppc_altivec_vcmpequw_p:
case Intrinsic::ppc_altivec_vcmpequd_p:
case Intrinsic::ppc_altivec_vcmpequq_p:
case Intrinsic::ppc_altivec_vcmpgefp_p:
case Intrinsic::ppc_altivec_vcmpgtfp_p:
case Intrinsic::ppc_altivec_vcmpgtsb_p:
case Intrinsic::ppc_altivec_vcmpgtsh_p:
case Intrinsic::ppc_altivec_vcmpgtsw_p:
case Intrinsic::ppc_altivec_vcmpgtsd_p:
case Intrinsic::ppc_altivec_vcmpgtsq_p:
case Intrinsic::ppc_altivec_vcmpgtub_p:
case Intrinsic::ppc_altivec_vcmpgtuh_p:
case Intrinsic::ppc_altivec_vcmpgtuw_p:
case Intrinsic::ppc_altivec_vcmpgtud_p:
case Intrinsic::ppc_altivec_vcmpgtuq_p:
Known.Zero = ~1U; // All bits but the low one are known to be zero.
break;
}
Expand Down
278 changes: 278 additions & 0 deletions llvm/test/CodeGen/PowerPC/vec_cmpq.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@
; 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
}

declare i32 @llvm.ppc.altivec.vcmpequq.p(i32, <1 x i128>, <1 x i128>) nounwind readnone
declare i32 @llvm.ppc.altivec.vcmpgtsq.p(i32, <1 x i128>, <1 x i128>) nounwind readnone
declare i32 @llvm.ppc.altivec.vcmpgtuq.p(i32, <1 x i128>, <1 x i128>) nounwind readnone

define i32 @test_vcmpequq_p(<1 x i128> %x, <1 x i128> %y) {
%tmp = tail call i32 @llvm.ppc.altivec.vcmpequq.p(i32 2, <1 x i128> %x, <1 x i128> %y)
ret i32 %tmp
; CHECK-LABEL: test_vcmpequq_p:
; CHECK: vcmpequq. {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
; CHECK: blr
}

define i32 @test_vcmpgtsq_p(<1 x i128> %x, <1 x i128> %y) {
%tmp = tail call i32 @llvm.ppc.altivec.vcmpgtsq.p(i32 2, <1 x i128> %x, <1 x i128> %y)
ret i32 %tmp
; CHECK-LABEL: test_vcmpgtsq_p
; CHECK: vcmpgtsq. {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
; CHECK: blr
}

define i32 @test_vcmpgtuq_p(<1 x i128> %x, <1 x i128> %y) {
%tmp = tail call i32 @llvm.ppc.altivec.vcmpgtuq.p(i32 2, <1 x i128> %x, <1 x i128> %y)
ret i32 %tmp
; CHECK-LABEL: test_vcmpgtuq_p
; CHECK: vcmpgtuq. {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
; CHECK: blr
}