[llvm-commits] [llvm] r167015 - in /llvm/trunk: lib/Target/PowerPC/PPCISelDAGToDAG.cpp lib/Target/PowerPC/PPCISelLowering.cpp test/CodeGen/PowerPC/vec_cmp.ll
Alex Rosenberg
alexr at leftfield.org
Wed Oct 31 16:33:59 PDT 2012
On Oct 30, 2012, at 6:50 AM, Adhemerval Zanella <azanella at linux.vnet.ibm.com> wrote:
> Author: azanella
> Date: Tue Oct 30 08:50:19 2012
> New Revision: 167015
>
> URL: http://llvm.org/viewvc/llvm-project?rev=167015&view=rev
> Log:
> PowerPC: More support for Altivec compare operations
>
> This patch adds more support for vector type comparisons using altivec.
> It adds correct support for v16i8, v8i16, v4i32, and v4f32 vector
> types for comparison operators ==, !=, >, >=, <, and <=.
>
>
> Modified:
> llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
> llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
> llvm/trunk/test/CodeGen/PowerPC/vec_cmp.ll
>
> Modified: llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp?rev=167015&r1=167014&r2=167015&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp (original)
> +++ llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Tue Oct 30 08:50:19 2012
> @@ -623,6 +623,88 @@
> }
> }
>
> +// 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, and v4f32).
> +static unsigned int getVCmpInst(MVT::SimpleValueType VecVT, ISD::CondCode CC) {
> + switch (CC) {
> + case ISD::SETEQ:
> + case ISD::SETUEQ:
> + case ISD::SETNE:
> + case ISD::SETUNE:
> + if (VecVT == MVT::v16i8)
> + return PPC::VCMPEQUB;
> + else if (VecVT == MVT::v8i16)
> + return PPC::VCMPEQUH;
> + else if (VecVT == MVT::v4i32)
> + return PPC::VCMPEQUW;
> + // v4f32 != v4f32 could be translate to unordered not equal
> + else if (VecVT == MVT::v4f32)
> + return PPC::VCMPEQFP;
> + break;
> + case ISD::SETLT:
> + case ISD::SETGT:
> + case ISD::SETLE:
> + case ISD::SETGE:
> + if (VecVT == MVT::v16i8)
> + return PPC::VCMPGTSB;
> + else if (VecVT == MVT::v8i16)
> + return PPC::VCMPGTSH;
> + else if (VecVT == MVT::v4i32)
> + return PPC::VCMPGTSW;
> + else if (VecVT == MVT::v4f32)
> + return PPC::VCMPGTFP;
> + break;
> + case ISD::SETULT:
> + case ISD::SETUGT:
> + case ISD::SETUGE:
> + case ISD::SETULE:
> + if (VecVT == MVT::v16i8)
> + return PPC::VCMPGTUB;
> + else if (VecVT == MVT::v8i16)
> + return PPC::VCMPGTUH;
> + else if (VecVT == MVT::v4i32)
> + return PPC::VCMPGTUW;
> + break;
> + case ISD::SETOEQ:
> + if (VecVT == MVT::v4f32)
> + return PPC::VCMPEQFP;
> + break;
> + case ISD::SETOLT:
> + case ISD::SETOGT:
> + case ISD::SETOLE:
> + if (VecVT == MVT::v4f32)
> + return PPC::VCMPGTFP;
> + break;
> + case ISD::SETOGE:
> + if (VecVT == MVT::v4f32)
> + return PPC::VCMPGEFP;
> + break;
> + default:
> + break;
> + }
> + llvm_unreachable("Invalid integer vector compare condition");
> +}
> +
> +// getVCmpEQInst: return the equal compare instruction for the specified vector
> +// type. Since this is for altivec specific code, only support the altivec
> +// types (v16i8, v8i16, v4i32, and v4f32).
> +static unsigned int getVCmpEQInst(MVT::SimpleValueType VecVT) {
> + switch (VecVT) {
> + case MVT::v16i8:
> + return PPC::VCMPEQUB;
> + case MVT::v8i16:
> + return PPC::VCMPEQUH;
> + case MVT::v4i32:
> + return PPC::VCMPEQUW;
> + case MVT::v4f32:
> + return PPC::VCMPEQFP;
> + default:
> + llvm_unreachable("Invalid integer vector compare condition");
> + }
> +}
> +
> +
> SDNode *PPCDAGToDAGISel::SelectSETCC(SDNode *N) {
> DebugLoc dl = N->getDebugLoc();
> unsigned Imm;
> @@ -706,20 +788,58 @@
> SDValue LHS = N->getOperand(0);
> SDValue RHS = N->getOperand(1);
>
> - // Altivec Vector compare instructions do not set any CR register by default
> + // Altivec Vector compare instructions do not set any CR register by default and
> + // vector compare operations return the same type as the operands.
> if (LHS.getValueType().isVector()) {
> - unsigned int Opc;
> - if (LHS.getValueType() == MVT::v16i8)
> - Opc = PPC::VCMPEQUB;
> - else if (LHS.getValueType() == MVT::v4i32)
> - Opc = PPC::VCMPEQUW;
> - else if (LHS.getValueType() == MVT::v8i16)
> - Opc = PPC::VCMPEQUH;
> - else if (LHS.getValueType() == MVT::v4f32)
> - Opc = PPC::VCMPEQFP;
> - else
> - llvm_unreachable("Invalid vector compare type: should be expanded by legalize");
> - return CurDAG->SelectNodeTo(N, Opc, LHS.getValueType(), LHS, RHS);
> + EVT VecVT = LHS.getValueType();
> + MVT::SimpleValueType VT = VecVT.getSimpleVT().SimpleTy;
> + unsigned int VCmpInst = getVCmpInst(VT, CC);
> +
> + switch (CC) {
> + case ISD::SETEQ:
> + case ISD::SETOEQ:
> + case ISD::SETUEQ:
> + return CurDAG->SelectNodeTo(N, VCmpInst, VecVT, LHS, RHS);
> + case ISD::SETNE:
> + case ISD::SETONE:
> + case ISD::SETUNE: {
> + SDValue VCmp(CurDAG->getMachineNode(VCmpInst, dl, VecVT, LHS, RHS), 0);
> + return CurDAG->SelectNodeTo(N, PPC::VNOR, VecVT, VCmp, VCmp);
> + }
I'm not an expert on the SET ops, but I'm wondering if these VNOTs can potentially be eliminated by flipping the uses.
Alex
> + case ISD::SETLT:
> + case ISD::SETOLT:
> + case ISD::SETULT:
> + return CurDAG->SelectNodeTo(N, VCmpInst, VecVT, RHS, LHS);
> + case ISD::SETGT:
> + case ISD::SETOGT:
> + case ISD::SETUGT:
> + return CurDAG->SelectNodeTo(N, VCmpInst, VecVT, LHS, RHS);
> + case ISD::SETGE:
> + case ISD::SETOGE:
> + case ISD::SETUGE: {
> + // Small optimization: Altivec provides a 'Vector Compare Greater Than
> + // or Equal To' instruction (vcmpgefp), so in this case there is no
> + // need for extra logic for the equal compare.
> + if (VecVT.getSimpleVT().isFloatingPoint()) {
> + return CurDAG->SelectNodeTo(N, VCmpInst, VecVT, LHS, RHS);
> + } else {
> + SDValue VCmpGT(CurDAG->getMachineNode(VCmpInst, dl, VecVT, LHS, RHS), 0);
> + unsigned int VCmpEQInst = getVCmpEQInst(VT);
> + SDValue VCmpEQ(CurDAG->getMachineNode(VCmpEQInst, dl, VecVT, LHS, RHS), 0);
> + return CurDAG->SelectNodeTo(N, PPC::VOR, VecVT, VCmpGT, VCmpEQ);
> + }
> + }
> + case ISD::SETLE:
> + case ISD::SETOLE:
> + case ISD::SETULE: {
> + SDValue VCmpLE(CurDAG->getMachineNode(VCmpInst, dl, VecVT, RHS, LHS), 0);
> + unsigned int VCmpEQInst = getVCmpEQInst(VT);
> + SDValue VCmpEQ(CurDAG->getMachineNode(VCmpEQInst, dl, VecVT, LHS, RHS), 0);
> + return CurDAG->SelectNodeTo(N, PPC::VOR, VecVT, VCmpLE, VCmpEQ);
> + }
> + default:
> + llvm_unreachable("Invalid vector compare type: should be expanded by legalize");
> + }
> }
>
> bool Inv;
>
> Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=167015&r1=167014&r2=167015&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Tue Oct 30 08:50:19 2012
> @@ -396,6 +396,14 @@
> setOperationAction(ISD::BUILD_VECTOR, MVT::v8i16, Custom);
> setOperationAction(ISD::BUILD_VECTOR, MVT::v4i32, Custom);
> setOperationAction(ISD::BUILD_VECTOR, MVT::v4f32, Custom);
> +
> + // Altivec does not contain unordered floating-point compare instructions
> + setCondCodeAction(ISD::SETUO, MVT::v4f32, Expand);
> + setCondCodeAction(ISD::SETUEQ, MVT::v4f32, Expand);
> + setCondCodeAction(ISD::SETUGT, MVT::v4f32, Expand);
> + setCondCodeAction(ISD::SETUGE, MVT::v4f32, Expand);
> + setCondCodeAction(ISD::SETULT, MVT::v4f32, Expand);
> + setCondCodeAction(ISD::SETULE, MVT::v4f32, Expand);
> }
>
> if (Subtarget->has64BitSupport()) {
>
> Modified: llvm/trunk/test/CodeGen/PowerPC/vec_cmp.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/vec_cmp.ll?rev=167015&r1=167014&r2=167015&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/PowerPC/vec_cmp.ll (original)
> +++ llvm/trunk/test/CodeGen/PowerPC/vec_cmp.ll Tue Oct 30 08:50:19 2012
> @@ -1,6 +1,9 @@
> -; RUN: llc -mattr=+altivec < %s | FileCheck %s
> +; RUN: llc -mcpu=pwr6 -mattr=+altivec < %s | FileCheck %s
>
> -; Check vector comparisons using altivec.
> +; Check vector comparisons using altivec. For non native types, just basic
> +; comparison instruction check is done. For altivec supported type (16i8,
> +; 8i16, 4i32, and 4f32) all the comparisons operators (==, !=, >, >=, <, <=)
> +; are checked.
>
>
> target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64"
> @@ -33,13 +36,105 @@
> ; CHECK: vcmpequh {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
>
>
> -define <16 x i8> @v16si8_cmp(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
> +; Adicional tests for v16i8 since it is a altivec native type
> +
> +define <16 x i8> @v16si8_cmp_eq(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
> %cmp = icmp eq <16 x i8> %x, %y
> %sext = sext <16 x i1> %cmp to <16 x i8>
> ret <16 x i8> %sext
> }
> -; CHECK: v16si8_cmp:
> -; CHECK: vcmpequb {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
> +; CHECK: v16si8_cmp_eq:
> +; CHECK: vcmpequb 2, 2, 3
> +
> +define <16 x i8> @v16si8_cmp_ne(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
> +entry:
> + %cmp = icmp ne <16 x i8> %x, %y
> + %sext = sext <16 x i1> %cmp to <16 x i8>
> + ret <16 x i8> %sext
> +}
> +; CHECK: v16si8_cmp_ne:
> +; CHECK: vcmpequb [[RET:[0-9]+]], 2, 3
> +; CHECK-NOR: vnor 2, [[RET]], [[RET]]
> +
> +define <16 x i8> @v16si8_cmp_le(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
> +entry:
> + %cmp = icmp sle <16 x i8> %x, %y
> + %sext = sext <16 x i1> %cmp to <16 x i8>
> + ret <16 x i8> %sext
> +}
> +; CHECK: v16si8_cmp_le:
> +; CHECK: vcmpequb [[RCMPEQ:[0-9]+]], 2, 3
> +; CHECK-NEXT: vcmpgtsb [[RCMPLE:[0-9]+]], 3, 2
> +; CHECK-NEXT: vor 2, [[RCMPLE]], [[RCMPEQ]]
> +
> +define <16 x i8> @v16ui8_cmp_le(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
> +entry:
> + %cmp = icmp ule <16 x i8> %x, %y
> + %sext = sext <16 x i1> %cmp to <16 x i8>
> + ret <16 x i8> %sext
> +}
> +; CHECK: v16ui8_cmp_le:
> +; CHECK: vcmpequb [[RCMPEQ:[0-9]+]], 2, 3
> +; CHECK-NEXT: vcmpgtub [[RCMPLE:[0-9]+]], 3, 2
> +; CHECK-NEXT: vor 2, [[RCMPLE]], [[RCMPEQ]]
> +
> +define <16 x i8> @v16si8_cmp_lt(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
> +entry:
> + %cmp = icmp slt <16 x i8> %x, %y
> + %sext = sext <16 x i1> %cmp to <16 x i8>
> + ret <16 x i8> %sext
> +}
> +; CHECK: v16si8_cmp_lt:
> +; CHECK: vcmpgtsb 2, 3, 2
> +
> +define <16 x i8> @v16ui8_cmp_lt(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
> +entry:
> + %cmp = icmp ult <16 x i8> %x, %y
> + %sext = sext <16 x i1> %cmp to <16 x i8>
> + ret <16 x i8> %sext
> +}
> +; CHECK: v16ui8_cmp_lt:
> +; CHECK: vcmpgtub 2, 3, 2
> +
> +define <16 x i8> @v16si8_cmp_gt(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
> +entry:
> + %cmp = icmp sgt <16 x i8> %x, %y
> + %sext = sext <16 x i1> %cmp to <16 x i8>
> + ret <16 x i8> %sext
> +}
> +; CHECK: v16si8_cmp_gt:
> +; CHECK: vcmpgtsb 2, 2, 3
> +
> +define <16 x i8> @v16ui8_cmp_gt(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
> +entry:
> + %cmp = icmp ugt <16 x i8> %x, %y
> + %sext = sext <16 x i1> %cmp to <16 x i8>
> + ret <16 x i8> %sext
> +}
> +; CHECK: v16ui8_cmp_gt:
> +; CHECK: vcmpgtub 2, 2, 3
> +
> +define <16 x i8> @v16si8_cmp_ge(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
> +entry:
> + %cmp = icmp sge <16 x i8> %x, %y
> + %sext = sext <16 x i1> %cmp to <16 x i8>
> + ret <16 x i8> %sext
> +}
> +; CHECK: v16si8_cmp_ge:
> +; CHECK: vcmpequb [[RCMPEQ:[0-9]+]], 2, 3
> +; CHECK-NEXT: vcmpgtsb [[RCMPGT:[0-9]+]], 2, 3
> +; CHECK-NEXT: vor 2, [[RCMPGT]], [[RCMPEQ]]
> +
> +define <16 x i8> @v16ui8_cmp_ge(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
> +entry:
> + %cmp = icmp uge <16 x i8> %x, %y
> + %sext = sext <16 x i1> %cmp to <16 x i8>
> + ret <16 x i8> %sext
> +}
> +; CHECK: v16ui8_cmp_ge:
> +; CHECK: vcmpequb [[RCMPEQ:[0-9]+]], 2, 3
> +; CHECK-NEXT: vcmpgtub [[RCMPGT:[0-9]+]], 2, 3
> +; CHECK-NEXT: vor 2, [[RCMPGT]], [[RCMPEQ]]
>
>
> define <32 x i8> @v32si8_cmp(<32 x i8> %x, <32 x i8> %y) nounwind readnone {
> @@ -70,13 +165,106 @@
> ; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
>
>
> -define <8 x i16> @v8si16_cmp(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
> +; Adicional tests for v8i16 since it is an altivec native type
> +
> +define <8 x i16> @v8si16_cmp_eq(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
> +entry:
> %cmp = icmp eq <8 x i16> %x, %y
> %sext = sext <8 x i1> %cmp to <8 x i16>
> ret <8 x i16> %sext
> }
> -; CHECK: v8si16_cmp:
> -; CHECK: vcmpequh {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
> +; CHECK: v8si16_cmp_eq:
> +; CHECK: vcmpequh 2, 2, 3
> +
> +define <8 x i16> @v8si16_cmp_ne(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
> +entry:
> + %cmp = icmp ne <8 x i16> %x, %y
> + %sext = sext <8 x i1> %cmp to <8 x i16>
> + ret <8 x i16> %sext
> +}
> +; CHECK: v8si16_cmp_ne:
> +; CHECK: vcmpequh [[RET:[0-9]+]], 2, 3
> +; CHECK-NEXT: vnor 2, [[RET]], [[RET]]
> +
> +define <8 x i16> @v8si16_cmp_le(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
> +entry:
> + %cmp = icmp sle <8 x i16> %x, %y
> + %sext = sext <8 x i1> %cmp to <8 x i16>
> + ret <8 x i16> %sext
> +}
> +; CHECK: v8si16_cmp_le:
> +; CHECK: vcmpequh [[RCMPEQ:[0-9]+]], 2, 3
> +; CHECK-NEXT: vcmpgtsh [[RCMPLE:[0-9]+]], 3, 2
> +; CHECK-NEXT: vor 2, [[RCMPLE]], [[RCMPEQ]]
> +
> +define <8 x i16> @v8ui16_cmp_le(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
> +entry:
> + %cmp = icmp ule <8 x i16> %x, %y
> + %sext = sext <8 x i1> %cmp to <8 x i16>
> + ret <8 x i16> %sext
> +}
> +; CHECK: v8ui16_cmp_le:
> +; CHECK: vcmpequh [[RCMPEQ:[0-9]+]], 2, 3
> +; CHECK-NEXT: vcmpgtuh [[RCMPLE:[0-9]+]], 3, 2
> +; CHECK-NEXT: vor 2, [[RCMPLE]], [[RCMPEQ]]
> +
> +define <8 x i16> @v8si16_cmp_lt(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
> +entry:
> + %cmp = icmp slt <8 x i16> %x, %y
> + %sext = sext <8 x i1> %cmp to <8 x i16>
> + ret <8 x i16> %sext
> +}
> +; CHECK: v8si16_cmp_lt:
> +; CHECK: vcmpgtsh 2, 3, 2
> +
> +define <8 x i16> @v8ui16_cmp_lt(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
> +entry:
> + %cmp = icmp ult <8 x i16> %x, %y
> + %sext = sext <8 x i1> %cmp to <8 x i16>
> + ret <8 x i16> %sext
> +}
> +; CHECK: v8ui16_cmp_lt:
> +; CHECK: vcmpgtuh 2, 3, 2
> +
> +define <8 x i16> @v8si16_cmp_gt(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
> +entry:
> + %cmp = icmp sgt <8 x i16> %x, %y
> + %sext = sext <8 x i1> %cmp to <8 x i16>
> + ret <8 x i16> %sext
> +}
> +; CHECK: v8si16_cmp_gt:
> +; CHECK: vcmpgtsh 2, 2, 3
> +
> +define <8 x i16> @v8ui16_cmp_gt(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
> +entry:
> + %cmp = icmp ugt <8 x i16> %x, %y
> + %sext = sext <8 x i1> %cmp to <8 x i16>
> + ret <8 x i16> %sext
> +}
> +; CHECK: v8ui16_cmp_gt:
> +; CHECK: vcmpgtuh 2, 2, 3
> +
> +define <8 x i16> @v8si16_cmp_ge(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
> +entry:
> + %cmp = icmp sge <8 x i16> %x, %y
> + %sext = sext <8 x i1> %cmp to <8 x i16>
> + ret <8 x i16> %sext
> +}
> +; CHECK: v8si16_cmp_ge:
> +; CHECK: vcmpequh [[RCMPEQ:[0-9]+]], 2, 3
> +; CHECK-NEXT: vcmpgtsh [[RCMPGT:[0-9]+]], 2, 3
> +; CHECK-NEXT: vor 2, [[RCMPGT]], [[RCMPEQ]]
> +
> +define <8 x i16> @v8ui16_cmp_ge(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
> +entry:
> + %cmp = icmp uge <8 x i16> %x, %y
> + %sext = sext <8 x i1> %cmp to <8 x i16>
> + ret <8 x i16> %sext
> +}
> +; CHECK: v8ui16_cmp_ge:
> +; CHECK: vcmpequh [[RCMPEQ:[0-9]+]], 2, 3
> +; CHECK-NEXT: vcmpgtuh [[RCMPGT:[0-9]+]], 2, 3
> +; CHECK-NEXT: vor 2, [[RCMPGT]], [[RCMPEQ]]
>
>
> define <16 x i16> @v16si16_cmp(<16 x i16> %x, <16 x i16> %y) nounwind readnone {
> @@ -110,13 +298,106 @@
> ; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
>
>
> -define <4 x i32> @v4si32_cmp(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
> +; Adicional tests for v4si32 since it is an altivec native type
> +
> +define <4 x i32> @v4si32_cmp_eq(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
> +entry:
> %cmp = icmp eq <4 x i32> %x, %y
> %sext = sext <4 x i1> %cmp to <4 x i32>
> ret <4 x i32> %sext
> }
> -; CHECK: v4si32_cmp:
> -; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
> +; CHECK: v4si32_cmp_eq:
> +; CHECK: vcmpequw 2, 2, 3
> +
> +define <4 x i32> @v4si32_cmp_ne(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
> +entry:
> + %cmp = icmp ne <4 x i32> %x, %y
> + %sext = sext <4 x i1> %cmp to <4 x i32>
> + ret <4 x i32> %sext
> +}
> +; CHECK: v4si32_cmp_ne:
> +; CHECK: vcmpequw [[RCMP:[0-9]+]], 2, 3
> +; CHECK-NEXT: vnor 2, [[RCMP]], [[RCMP]]
> +
> +define <4 x i32> @v4si32_cmp_le(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
> +entry:
> + %cmp = icmp sle <4 x i32> %x, %y
> + %sext = sext <4 x i1> %cmp to <4 x i32>
> + ret <4 x i32> %sext
> +}
> +; CHECK: v4si32_cmp_le:
> +; CHECK: vcmpequw [[RCMPEQ:[0-9]+]], 2, 3
> +; CHECK-NEXT: vcmpgtsw [[RCMPLE:[0-9]+]], 3, 2
> +; CHECK-NEXT: vor 2, [[RCMPLE]], [[RCMPEQ]]
> +
> +define <4 x i32> @v4ui32_cmp_le(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
> +entry:
> + %cmp = icmp ule <4 x i32> %x, %y
> + %sext = sext <4 x i1> %cmp to <4 x i32>
> + ret <4 x i32> %sext
> +}
> +; CHECK: v4ui32_cmp_le:
> +; CHECK: vcmpequw [[RCMPEQ:[0-9]+]], 2, 3
> +; CHECK-NEXT: vcmpgtuw [[RCMPLE:[0-9]+]], 3, 2
> +; CHECK-NEXT: vor 2, [[RCMPLE]], [[RCMPEQ]]
> +
> +define <4 x i32> @v4si32_cmp_lt(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
> +entry:
> + %cmp = icmp slt <4 x i32> %x, %y
> + %sext = sext <4 x i1> %cmp to <4 x i32>
> + ret <4 x i32> %sext
> +}
> +; CHECK: v4si32_cmp_lt:
> +; CHECK: vcmpgtsw 2, 3, 2
> +
> +define <4 x i32> @v4ui32_cmp_lt(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
> +entry:
> + %cmp = icmp ult <4 x i32> %x, %y
> + %sext = sext <4 x i1> %cmp to <4 x i32>
> + ret <4 x i32> %sext
> +}
> +; CHECK: v4ui32_cmp_lt:
> +; CHECK: vcmpgtuw 2, 3, 2
> +
> +define <4 x i32> @v4si32_cmp_gt(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
> +entry:
> + %cmp = icmp sgt <4 x i32> %x, %y
> + %sext = sext <4 x i1> %cmp to <4 x i32>
> + ret <4 x i32> %sext
> +}
> +; CHECK: v4si32_cmp_gt:
> +; CHECK: vcmpgtsw 2, 2, 3
> +
> +define <4 x i32> @v4ui32_cmp_gt(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
> +entry:
> + %cmp = icmp ugt <4 x i32> %x, %y
> + %sext = sext <4 x i1> %cmp to <4 x i32>
> + ret <4 x i32> %sext
> +}
> +; CHECK: v4ui32_cmp_gt:
> +; CHECK: vcmpgtuw 2, 2, 3
> +
> +define <4 x i32> @v4si32_cmp_ge(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
> +entry:
> + %cmp = icmp sge <4 x i32> %x, %y
> + %sext = sext <4 x i1> %cmp to <4 x i32>
> + ret <4 x i32> %sext
> +}
> +; CHECK: v4si32_cmp_ge:
> +; CHECK: vcmpequw [[RCMPEQ:[0-9]+]], 2, 3
> +; CHECK-NEXT: vcmpgtsw [[RCMPGT:[0-9]+]], 2, 3
> +; CHECK-NEXT: vor 2, [[RCMPGT]], [[RCMPEQ]]
> +
> +define <4 x i32> @v4ui32_cmp_ge(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
> +entry:
> + %cmp = icmp uge <4 x i32> %x, %y
> + %sext = sext <4 x i1> %cmp to <4 x i32>
> + ret <4 x i32> %sext
> +}
> +; CHECK: v4ui32_cmp_ge:
> +; CHECK: vcmpequw [[RCMPEQ:[0-9]+]], 2, 3
> +; CHECK-NEXT: vcmpgtuw [[RCMPGT:[0-9]+]], 2, 3
> +; CHECK-NEXT: vor 2, [[RCMPGT]], [[RCMPEQ]]
>
>
> define <8 x i32> @v8si32_cmp(<8 x i32> %x, <8 x i32> %y) nounwind readnone {
> @@ -168,15 +449,70 @@
> ; CHECK: vcmpeqfp {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
>
>
> -define <4 x float> @v4f32_cmp(<4 x float> %x, <4 x float> %y) nounwind readnone {
> +; Adicional tests for v4f32 since it is a altivec native type
> +
> +define <4 x float> @v4f32_cmp_eq(<4 x float> %x, <4 x float> %y) nounwind readnone {
> entry:
> %cmp = fcmp oeq <4 x float> %x, %y
> %sext = sext <4 x i1> %cmp to <4 x i32>
> %0 = bitcast <4 x i32> %sext to <4 x float>
> ret <4 x float> %0
> }
> -; CHECK: v4f32_cmp:
> -; CHECK: vcmpeqfp {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
> +; CHECK: v4f32_cmp_eq:
> +; CHECK: vcmpeqfp 2, 2, 3
> +
> +define <4 x float> @v4f32_cmp_ne(<4 x float> %x, <4 x float> %y) nounwind readnone {
> +entry:
> + %cmp = fcmp une <4 x float> %x, %y
> + %sext = sext <4 x i1> %cmp to <4 x i32>
> + %0 = bitcast <4 x i32> %sext to <4 x float>
> + ret <4 x float> %0
> +}
> +; CHECK: v4f32_cmp_ne:
> +; CHECK: vcmpeqfp [[RET:[0-9]+]], 2, 3
> +; CHECK-NEXT: vnor 2, [[RET]], [[RET]]
> +
> +define <4 x float> @v4f32_cmp_le(<4 x float> %x, <4 x float> %y) nounwind readnone {
> +entry:
> + %cmp = fcmp ole <4 x float> %x, %y
> + %sext = sext <4 x i1> %cmp to <4 x i32>
> + %0 = bitcast <4 x i32> %sext to <4 x float>
> + ret <4 x float> %0
> +}
> +; CHECK: v4f32_cmp_le:
> +; CHECK: vcmpeqfp [[RCMPEQ:[0-9]+]], 2, 3
> +; CHECK-NEXT: vcmpgtfp [[RCMPLE:[0-9]+]], 3, 2
> +; CHECK-NEXT: vor 2, [[RCMPLE]], [[RCMPEQ]]
> +
> +define <4 x float> @v4f32_cmp_lt(<4 x float> %x, <4 x float> %y) nounwind readnone {
> +entry:
> + %cmp = fcmp olt <4 x float> %x, %y
> + %sext = sext <4 x i1> %cmp to <4 x i32>
> + %0 = bitcast <4 x i32> %sext to <4 x float>
> + ret <4 x float> %0
> +}
> +; CHECK: v4f32_cmp_lt:
> +; CHECK: vcmpgtfp 2, 3, 2
> +
> +define <4 x float> @v4f32_cmp_ge(<4 x float> %x, <4 x float> %y) nounwind readnone {
> +entry:
> + %cmp = fcmp oge <4 x float> %x, %y
> + %sext = sext <4 x i1> %cmp to <4 x i32>
> + %0 = bitcast <4 x i32> %sext to <4 x float>
> + ret <4 x float> %0
> +}
> +; CHECK: v4f32_cmp_ge:
> +; CHECK: vcmpgefp 2, 2, 3
> +
> +define <4 x float> @v4f32_cmp_gt(<4 x float> %x, <4 x float> %y) nounwind readnone {
> +entry:
> + %cmp = fcmp ogt <4 x float> %x, %y
> + %sext = sext <4 x i1> %cmp to <4 x i32>
> + %0 = bitcast <4 x i32> %sext to <4 x float>
> + ret <4 x float> %0
> +}
> +; CHECK: v4f32_cmp_gt:
> +; CHECK: vcmpgtfp 2, 2, 3
>
>
> define <8 x float> @v8f32_cmp(<8 x float> %x, <8 x float> %y) nounwind readnone {
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list