[PATCH v3 1/1] R600: Implement float to long/ulong

Tom Stellard tom at stellard.net
Wed Jun 25 09:17:57 PDT 2014


On Tue, Jun 24, 2014 at 07:09:12PM -0400, Jan Vesely wrote:
> Use alg. from LegalizeDAG.cpp
> Move Expand setting to SIISellowering
> 
> v2: Extend existing tests instead of creating new ones
> v3: use separate LowerFPTOSINT function
>

We should solve this by moving the FP_TO_SINT lowering from LegalizeDAG.cpp
into TargetLowering, so that it can be shared between LegalizeDAG and
DAGTypeLegalizer.  Then we don't need to handle this in the backend.

Use commits r206036 and r206037 as an example for how this can be done.

-Tom
 
> Signed-off-by: Jan Vesely <jan.vesely at rutgers.edu>
> ---
>  lib/Target/R600/AMDGPUISelLowering.cpp |   1 -
>  lib/Target/R600/R600ISelLowering.cpp   |  66 +++++++++-
>  lib/Target/R600/R600ISelLowering.h     |   1 +
>  lib/Target/R600/SIISelLowering.cpp     |   3 +
>  test/CodeGen/R600/fp_to_sint.ll        | 213 ++++++++++++++++++++++++++++++---
>  test/CodeGen/R600/fp_to_sint_i64.ll    |  12 --
>  test/CodeGen/R600/fp_to_uint.ll        | 210 +++++++++++++++++++++++++++++---
>  7 files changed, 455 insertions(+), 51 deletions(-)
>  delete mode 100644 test/CodeGen/R600/fp_to_sint_i64.ll
> 
> diff --git a/lib/Target/R600/AMDGPUISelLowering.cpp b/lib/Target/R600/AMDGPUISelLowering.cpp
> index 07c82b1..500b0e5 100644
> --- a/lib/Target/R600/AMDGPUISelLowering.cpp
> +++ b/lib/Target/R600/AMDGPUISelLowering.cpp
> @@ -265,7 +265,6 @@ AMDGPUTargetLowering::AMDGPUTargetLowering(TargetMachine &TM) :
>    setOperationAction(ISD::ROTL, MVT::i64, Expand);
>    setOperationAction(ISD::ROTR, MVT::i64, Expand);
>  
> -  setOperationAction(ISD::FP_TO_SINT, MVT::i64, Expand);
>    setOperationAction(ISD::MUL, MVT::i64, Expand);
>    setOperationAction(ISD::MULHU, MVT::i64, Expand);
>    setOperationAction(ISD::MULHS, MVT::i64, Expand);
> diff --git a/lib/Target/R600/R600ISelLowering.cpp b/lib/Target/R600/R600ISelLowering.cpp
> index 13d555e..932da1f 100644
> --- a/lib/Target/R600/R600ISelLowering.cpp
> +++ b/lib/Target/R600/R600ISelLowering.cpp
> @@ -82,6 +82,8 @@ R600TargetLowering::R600TargetLowering(TargetMachine &TM) :
>    setOperationAction(ISD::SETCC, MVT::i32, Expand);
>    setOperationAction(ISD::SETCC, MVT::f32, Expand);
>    setOperationAction(ISD::FP_TO_UINT, MVT::i1, Custom);
> +  setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
> +  setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom);
>  
>    setOperationAction(ISD::SELECT, MVT::i32, Expand);
>    setOperationAction(ISD::SELECT, MVT::f32, Expand);
> @@ -829,8 +831,15 @@ void R600TargetLowering::ReplaceNodeResults(SDNode *N,
>    default:
>      AMDGPUTargetLowering::ReplaceNodeResults(N, Results, DAG);
>      return;
> -  case ISD::FP_TO_UINT: Results.push_back(LowerFPTOUINT(N->getOperand(0), DAG));
> +  case ISD::FP_TO_UINT:
> +    if (N->getValueType(0) == MVT::i1) {
> +      Results.push_back(LowerFPTOUINT(N->getOperand(0), DAG));
> +      return;
> +    }
> +  case ISD::FP_TO_SINT: {
> +    Results.push_back(LowerFPTOSINT(SDValue(N, 0), DAG));
>      return;
> +  }
>    case ISD::LOAD: {
>      SDNode *Node = LowerLOAD(SDValue(N, 0), DAG).getNode();
>      Results.push_back(SDValue(Node, 0));
> @@ -1127,6 +1136,61 @@ SDValue R600TargetLowering::LowerFPTOUINT(SDValue Op, SelectionDAG &DAG) const {
>        DAG.getCondCode(ISD::SETNE)
>        );
>  }
> +SDValue R600TargetLowering::LowerFPTOSINT(SDValue Op, SelectionDAG &DAG) const {
> +    // This implementation is copied from LegalizeDAG.cpp and adapted
> +    // Expand f32 -> i64 conversion
> +    // This algorithm comes from compiler-rt's implementation of fixsfdi:
> +    // https://github.com/llvm-mirror/compiler-rt/blob/master/lib/builtins/fixsfdi.c
> +    EVT VT = Op.getOperand(0).getValueType();
> +    EVT NVT = Op.getValueType();
> +    SDLoc DL(Op);
> +    EVT IntVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits());
> +
> +    SDValue ExponentMask = DAG.getConstant(0x7F800000, IntVT);
> +    SDValue ExponentLoBit = DAG.getConstant(23, IntVT);
> +    SDValue Bias = DAG.getConstant(127, IntVT);
> +    SDValue SignMask = DAG.getConstant(APInt::getSignBit(VT.getSizeInBits()),
> +                                       IntVT);
> +    SDValue SignLowBit = DAG.getConstant(VT.getSizeInBits() - 1, IntVT);
> +    SDValue MantissaMask = DAG.getConstant(0x007FFFFF, IntVT);
> +
> +    SDValue Bits = DAG.getNode(ISD::BITCAST, DL, IntVT, Op.getOperand(0));
> +
> +    SDValue ExponentBits = DAG.getNode(ISD::SRL, DL, IntVT,
> +        DAG.getNode(ISD::AND, DL, IntVT, Bits, ExponentMask),
> +        DAG.getZExtOrTrunc(ExponentLoBit, DL, getShiftAmountTy(IntVT)));
> +    SDValue Exponent = DAG.getNode(ISD::SUB, DL, IntVT, ExponentBits, Bias);
> +
> +    SDValue Sign = DAG.getNode(ISD::SRA, DL, IntVT,
> +        DAG.getNode(ISD::AND, DL, IntVT, Bits, SignMask),
> +        DAG.getZExtOrTrunc(SignLowBit, DL, getShiftAmountTy(IntVT)));
> +    Sign = DAG.getSExtOrTrunc(Sign, DL, NVT);
> +
> +    SDValue R = DAG.getNode(ISD::OR, DL, IntVT,
> +        DAG.getNode(ISD::AND, DL, IntVT, Bits, MantissaMask),
> +        DAG.getConstant(0x00800000, IntVT));
> +
> +    R = DAG.getZExtOrTrunc(R, DL, NVT);
> +
> +
> +    R = DAG.getSelectCC(DL, Exponent, ExponentLoBit,
> +       DAG.getNode(ISD::SHL, DL, NVT, R,
> +                   DAG.getZExtOrTrunc(
> +                      DAG.getNode(ISD::SUB, DL, IntVT, Exponent, ExponentLoBit),
> +                      DL, getShiftAmountTy(IntVT))),
> +       DAG.getNode(ISD::SRL, DL, NVT, R,
> +                   DAG.getZExtOrTrunc(
> +                      DAG.getNode(ISD::SUB, DL, IntVT, ExponentLoBit, Exponent),
> +                      DL, getShiftAmountTy(IntVT))),
> +       ISD::SETGT);
> +
> +    SDValue Ret = DAG.getNode(ISD::SUB, DL, NVT,
> +        DAG.getNode(ISD::XOR, DL, NVT, R, Sign),
> +        Sign);
> +
> +    return DAG.getSelectCC(DL, Exponent, DAG.getConstant(0, IntVT),
> +        DAG.getConstant(0, NVT), Ret, ISD::SETLT);
> +}
>  
>  SDValue R600TargetLowering::LowerImplicitParameter(SelectionDAG &DAG, EVT VT,
>                                                     SDLoc DL,
> diff --git a/lib/Target/R600/R600ISelLowering.h b/lib/Target/R600/R600ISelLowering.h
> index d22c8c9..e88b3b9 100644
> --- a/lib/Target/R600/R600ISelLowering.h
> +++ b/lib/Target/R600/R600ISelLowering.h
> @@ -58,6 +58,7 @@ private:
>    SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
>    SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const;
>    SDValue LowerFPTOUINT(SDValue Op, SelectionDAG &DAG) const;
> +  SDValue LowerFPTOSINT(SDValue Op, SelectionDAG &DAG) const;
>    SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const;
>    SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) const;
>    SDValue LowerTrig(SDValue Op, SelectionDAG &DAG) const;
> diff --git a/lib/Target/R600/SIISelLowering.cpp b/lib/Target/R600/SIISelLowering.cpp
> index 4a7e99a..0f66f45 100644
> --- a/lib/Target/R600/SIISelLowering.cpp
> +++ b/lib/Target/R600/SIISelLowering.cpp
> @@ -167,6 +167,9 @@ SITargetLowering::SITargetLowering(TargetMachine &TM) :
>  
>    setOperationAction(ISD::LOAD, MVT::i1, Custom);
>  
> +  setOperationAction(ISD::FP_TO_SINT, MVT::i64, Expand);
> +  setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand);
> +
>    setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
>    setOperationAction(ISD::GlobalAddress, MVT::i64, Custom);
>    setOperationAction(ISD::FrameIndex, MVT::i32, Custom);
> diff --git a/test/CodeGen/R600/fp_to_sint.ll b/test/CodeGen/R600/fp_to_sint.ll
> index 8302b4f..235045a 100644
> --- a/test/CodeGen/R600/fp_to_sint.ll
> +++ b/test/CodeGen/R600/fp_to_sint.ll
> @@ -1,31 +1,206 @@
> -; RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s --check-prefix=R600-CHECK
> -; RUN: llc < %s -march=r600 -mcpu=SI -verify-machineinstrs | FileCheck %s --check-prefix=SI-CHECK
> -
> -; R600-CHECK: @fp_to_sint_v2i32
> -; R600-CHECK: FLT_TO_INT {{\** *}}T{{[0-9]+\.[XYZW], PV\.[XYZW]}}
> -; R600-CHECK: FLT_TO_INT {{\** *}}T{{[0-9]+\.[XYZW], PV\.[XYZW]}}
> -; SI-CHECK: @fp_to_sint_v2i32
> -; SI-CHECK: V_CVT_I32_F32_e32
> -; SI-CHECK: V_CVT_I32_F32_e32
> +; RUN: llc -march=r600 -mcpu=redwood < %s | FileCheck %s --check-prefix=EG --check-prefix=FUNC
> +; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs < %s | FileCheck %s --check-prefix=SI --check-prefix=FUNC
> +
> +; FUNC-LABEL: @fp_to_sint_v2i32
> +; EG: FLT_TO_INT {{\** *}}T{{[0-9]+\.[XYZW], PV\.[XYZW]}}
> +; EG: FLT_TO_INT {{\** *}}T{{[0-9]+\.[XYZW], PV\.[XYZW]}}
> +; SI: V_CVT_I32_F32_e32
> +; SI: V_CVT_I32_F32_e32
>  define void @fp_to_sint_v2i32(<2 x i32> addrspace(1)* %out, <2 x float> %in) {
>    %result = fptosi <2 x float> %in to <2 x i32>
>    store <2 x i32> %result, <2 x i32> addrspace(1)* %out
>    ret void
>  }
>  
> -; R600-CHECK: @fp_to_sint_v4i32
> -; R600-CHECK: FLT_TO_INT {{\** *}}T{{[0-9]+\.[XYZW], PV\.[XYZW]}}
> -; R600-CHECK: FLT_TO_INT {{\** *}}T{{[0-9]+\.[XYZW]}}
> -; R600-CHECK: FLT_TO_INT {{\** *}}T{{[0-9]+\.[XYZW], PV\.[XYZW]}}
> -; R600-CHECK: FLT_TO_INT {{\** *}}T{{[0-9]+\.[XYZW], PV\.[XYZW]}}
> -; SI-CHECK: @fp_to_sint_v4i32
> -; SI-CHECK: V_CVT_I32_F32_e32
> -; SI-CHECK: V_CVT_I32_F32_e32
> -; SI-CHECK: V_CVT_I32_F32_e32
> -; SI-CHECK: V_CVT_I32_F32_e32
> +; FUNC-LABEL: @fp_to_sint_v4i32
> +; EG: FLT_TO_INT {{\** *}}T{{[0-9]+\.[XYZW], PV\.[XYZW]}}
> +; EG: FLT_TO_INT {{\** *}}T{{[0-9]+\.[XYZW]}}
> +; EG: FLT_TO_INT {{\** *}}T{{[0-9]+\.[XYZW], PV\.[XYZW]}}
> +; EG: FLT_TO_INT {{\** *}}T{{[0-9]+\.[XYZW], PV\.[XYZW]}}
> +; SI: V_CVT_I32_F32_e32
> +; SI: V_CVT_I32_F32_e32
> +; SI: V_CVT_I32_F32_e32
> +; SI: V_CVT_I32_F32_e32
>  define void @fp_to_sint_v4i32(<4 x i32> addrspace(1)* %out, <4 x float> addrspace(1)* %in) {
>    %value = load <4 x float> addrspace(1) * %in
>    %result = fptosi <4 x float> %value to <4 x i32>
>    store <4 x i32> %result, <4 x i32> addrspace(1)* %out
>    ret void
>  }
> +
> +; FUNC-LABEL: @fp_to_sint_i64
> +
> +; EG-DAG: AND_INT
> +; EG-DAG: LSHR
> +; EG-DAG: SUB_INT
> +; EG-DAG: AND_INT
> +; EG-DAG: ASHR
> +; EG-DAG: AND_INT
> +; EG-DAG: OR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHL
> +; EG-DAG: LSHL
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHR
> +; EG-DAG: LSHR
> +; EG-DAG: SETGT_UINT
> +; EG-DAG: SETGT_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: XOR_INT
> +; EG: SUB_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: CNDGE_INT
> +; EG-DAG: CNDGE_INT
> +
> +; Check that the compiler doesn't crash with a "cannot select" error
> +; SI: S_ENDPGM
> +define void @fp_to_sint_i64 (i64 addrspace(1)* %out, float %in) {
> +entry:
> +  %0 = fptosi float %in to i64
> +  store i64 %0, i64 addrspace(1)* %out
> +  ret void
> +}
> +
> +; FUNC: @fp_to_sint_v2i64
> +; EG-DAG: AND_INT
> +; EG-DAG: LSHR
> +; EG-DAG: SUB_INT
> +; EG-DAG: AND_INT
> +; EG-DAG: ASHR
> +; EG-DAG: AND_INT
> +; EG-DAG: OR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHL
> +; EG-DAG: LSHL
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHR
> +; EG-DAG: LSHR
> +; EG-DAG: SETGT_UINT
> +; EG-DAG: SETGT_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: CNDGE_INT
> +; EG-DAG: CNDGE_INT
> +; EG-DAG: AND_INT
> +; EG-DAG: LSHR
> +; EG-DAG: SUB_INT
> +; EG-DAG: AND_INT
> +; EG-DAG: ASHR
> +; EG-DAG: AND_INT
> +; EG-DAG: OR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHL
> +; EG-DAG: LSHL
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHR
> +; EG-DAG: LSHR
> +; EG-DAG: SETGT_UINT
> +; EG-DAG: SETGT_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: CNDGE_INT
> +; EG-DAG: CNDGE_INT
> +
> +; SI: S_ENDPGM
> +define void @fp_to_sint_v2i64(<2 x i64> addrspace(1)* %out, <2 x float> %x) {
> +  %conv = fptosi <2 x float> %x to <2 x i64>
> +  store <2 x i64> %conv, <2 x i64> addrspace(1)* %out
> +  ret void
> +}
> +
> +; FUNC: @fp_to_sint_v4i64
> +; EG-DAG: AND_INT
> +; EG-DAG: LSHR
> +; EG-DAG: SUB_INT
> +; EG-DAG: AND_INT
> +; EG-DAG: ASHR
> +; EG-DAG: AND_INT
> +; EG-DAG: OR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHL
> +; EG-DAG: LSHL
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHR
> +; EG-DAG: LSHR
> +; EG-DAG: SETGT_UINT
> +; EG-DAG: SETGT_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: CNDGE_INT
> +; EG-DAG: CNDGE_INT
> +; EG-DAG: AND_INT
> +; EG-DAG: LSHR
> +; EG-DAG: SUB_INT
> +; EG-DAG: AND_INT
> +; EG-DAG: ASHR
> +; EG-DAG: AND_INT
> +; EG-DAG: OR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHL
> +; EG-DAG: LSHL
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHR
> +; EG-DAG: LSHR
> +; EG-DAG: SETGT_UINT
> +; EG-DAG: SETGT_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: CNDGE_INT
> +; EG-DAG: CNDGE_INT
> +; EG-DAG: AND_INT
> +; EG-DAG: LSHR
> +; EG-DAG: SUB_INT
> +; EG-DAG: AND_INT
> +; EG-DAG: ASHR
> +; EG-DAG: AND_INT
> +; EG-DAG: OR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHL
> +; EG-DAG: LSHL
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHR
> +; EG-DAG: LSHR
> +; EG-DAG: SETGT_UINT
> +; EG-DAG: SETGT_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: CNDGE_INT
> +; EG-DAG: CNDGE_INT
> +; EG-DAG: AND_INT
> +; EG-DAG: LSHR
> +; EG-DAG: SUB_INT
> +; EG-DAG: AND_INT
> +; EG-DAG: ASHR
> +; EG-DAG: AND_INT
> +; EG-DAG: OR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHL
> +; EG-DAG: LSHL
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHR
> +; EG-DAG: LSHR
> +; EG-DAG: SETGT_UINT
> +; EG-DAG: SETGT_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: CNDGE_INT
> +; EG-DAG: CNDGE_INT
> +
> +; SI: S_ENDPGM
> +define void @fp_to_sint_v4i64(<4 x i64> addrspace(1)* %out, <4 x float> %x) {
> +  %conv = fptosi <4 x float> %x to <4 x i64>
> +  store <4 x i64> %conv, <4 x i64> addrspace(1)* %out
> +  ret void
> +}
> diff --git a/test/CodeGen/R600/fp_to_sint_i64.ll b/test/CodeGen/R600/fp_to_sint_i64.ll
> deleted file mode 100644
> index ec3e198..0000000
> --- a/test/CodeGen/R600/fp_to_sint_i64.ll
> +++ /dev/null
> @@ -1,12 +0,0 @@
> -; FIXME: Merge into fp_to_sint.ll when EG/NI supports 64-bit types
> -; RUN: llc < %s -march=r600 -mcpu=SI -verify-machineinstrs | FileCheck --check-prefix=SI %s
> -
> -; SI-LABEL: @fp_to_sint_i64
> -; Check that the compiler doesn't crash with a "cannot select" error
> -; SI: S_ENDPGM
> -define void @fp_to_sint_i64 (i64 addrspace(1)* %out, float %in) {
> -entry:
> -  %0 = fptosi float %in to i64
> -  store i64 %0, i64 addrspace(1)* %out
> -  ret void
> -}
> diff --git a/test/CodeGen/R600/fp_to_uint.ll b/test/CodeGen/R600/fp_to_uint.ll
> index 77db43b..a13018b 100644
> --- a/test/CodeGen/R600/fp_to_uint.ll
> +++ b/test/CodeGen/R600/fp_to_uint.ll
> @@ -1,12 +1,11 @@
> -; RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s --check-prefix=R600-CHECK
> -; RUN: llc < %s -march=r600 -mcpu=SI -verify-machineinstrs | FileCheck %s --check-prefix=SI-CHECK
> +; RUN: llc -march=r600 -mcpu=redwood < %s | FileCheck %s --check-prefix=EG --check-prefix=FUNC
> +; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs < %s | FileCheck %s --check-prefix=SI --check-prefix=FUNC
>  
> -; R600-CHECK: @fp_to_uint_v2i32
> -; R600-CHECK: FLT_TO_UINT {{\** *}}T{{[0-9]+\.[XYZW], PV\.[XYZW]}}
> -; R600-CHECK: FLT_TO_UINT {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
> -; SI-CHECK: @fp_to_uint_v2i32
> -; SI-CHECK: V_CVT_U32_F32_e32
> -; SI-CHECK: V_CVT_U32_F32_e32
> +; FUNC-LABEL: @fp_to_uint_v2i32
> +; EG: FLT_TO_UINT {{\** *}}T{{[0-9]+\.[XYZW], PV\.[XYZW]}}
> +; EG: FLT_TO_UINT {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
> +; SI: V_CVT_U32_F32_e32
> +; SI: V_CVT_U32_F32_e32
>  
>  define void @fp_to_uint_v2i32(<2 x i32> addrspace(1)* %out, <2 x float> %in) {
>    %result = fptoui <2 x float> %in to <2 x i32>
> @@ -14,16 +13,15 @@ define void @fp_to_uint_v2i32(<2 x i32> addrspace(1)* %out, <2 x float> %in) {
>    ret void
>  }
>  
> -; R600-CHECK: @fp_to_uint_v4i32
> -; R600-CHECK: FLT_TO_UINT {{\** *}}T{{[0-9]+\.[XYZW], PV\.[XYZW]}}
> -; R600-CHECK: FLT_TO_UINT {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
> -; R600-CHECK: FLT_TO_UINT {{\** *}}T{{[0-9]+\.[XYZW], PV\.[XYZW]}}
> -; R600-CHECK: FLT_TO_UINT {{\** *}}T{{[0-9]+\.[XYZW], PV\.[XYZW]}}
> -; SI-CHECK: @fp_to_uint_v4i32
> -; SI-CHECK: V_CVT_U32_F32_e32
> -; SI-CHECK: V_CVT_U32_F32_e32
> -; SI-CHECK: V_CVT_U32_F32_e32
> -; SI-CHECK: V_CVT_U32_F32_e32
> +; FUNC-LABEL: @fp_to_uint_v4i32
> +; EG: FLT_TO_UINT {{\** *}}T{{[0-9]+\.[XYZW], PV\.[XYZW]}}
> +; EG: FLT_TO_UINT {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
> +; EG: FLT_TO_UINT {{\** *}}T{{[0-9]+\.[XYZW], PV\.[XYZW]}}
> +; EG: FLT_TO_UINT {{\** *}}T{{[0-9]+\.[XYZW], PV\.[XYZW]}}
> +; SI: V_CVT_U32_F32_e32
> +; SI: V_CVT_U32_F32_e32
> +; SI: V_CVT_U32_F32_e32
> +; SI: V_CVT_U32_F32_e32
>  
>  define void @fp_to_uint_v4i32(<4 x i32> addrspace(1)* %out, <4 x float> addrspace(1)* %in) {
>    %value = load <4 x float> addrspace(1) * %in
> @@ -31,3 +29,179 @@ define void @fp_to_uint_v4i32(<4 x i32> addrspace(1)* %out, <4 x float> addrspac
>    store <4 x i32> %result, <4 x i32> addrspace(1)* %out
>    ret void
>  }
> +; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs < %s | FileCheck --check-prefix=SI --check-prefix=FUNC %s
> +; RUN: llc -march=r600 -mcpu=redwood < %s | FileCheck --check-prefix=EG --check-prefix=FUNC %s
> +
> +; FUNC: @fp_to_uint_i64
> +; EG-DAG: AND_INT
> +; EG-DAG: LSHR
> +; EG-DAG: SUB_INT
> +; EG-DAG: AND_INT
> +; EG-DAG: ASHR
> +; EG-DAG: AND_INT
> +; EG-DAG: OR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHL
> +; EG-DAG: LSHL
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHR
> +; EG-DAG: LSHR
> +; EG-DAG: SETGT_UINT
> +; EG-DAG: SETGT_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: XOR_INT
> +; EG: SUB_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: CNDGE_INT
> +; EG-DAG: CNDGE_INT
> +
> +; SI: S_ENDPGM
> +define void @fp_to_uint_i64(i64 addrspace(1)* %out, float %x) {
> +  %conv = fptoui float %x to i64
> +  store i64 %conv, i64 addrspace(1)* %out
> +  ret void
> +}
> +
> +; FUNC: @fp_to_uint_v2i64
> +; EG-DAG: AND_INT
> +; EG-DAG: LSHR
> +; EG-DAG: SUB_INT
> +; EG-DAG: AND_INT
> +; EG-DAG: ASHR
> +; EG-DAG: AND_INT
> +; EG-DAG: OR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHL
> +; EG-DAG: LSHL
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHR
> +; EG-DAG: LSHR
> +; EG-DAG: SETGT_UINT
> +; EG-DAG: SETGT_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: CNDGE_INT
> +; EG-DAG: CNDGE_INT
> +; EG-DAG: AND_INT
> +; EG-DAG: LSHR
> +; EG-DAG: SUB_INT
> +; EG-DAG: AND_INT
> +; EG-DAG: ASHR
> +; EG-DAG: AND_INT
> +; EG-DAG: OR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHL
> +; EG-DAG: LSHL
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHR
> +; EG-DAG: LSHR
> +; EG-DAG: SETGT_UINT
> +; EG-DAG: SETGT_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: CNDGE_INT
> +; EG-DAG: CNDGE_INT
> +
> +; SI: S_ENDPGM
> +define void @fp_to_uint_v2i64(<2 x i64> addrspace(1)* %out, <2 x float> %x) {
> +  %conv = fptoui <2 x float> %x to <2 x i64>
> +  store <2 x i64> %conv, <2 x i64> addrspace(1)* %out
> +  ret void
> +}
> +
> +; FUNC: @fp_to_uint_v4i64
> +; EG-DAG: AND_INT
> +; EG-DAG: LSHR
> +; EG-DAG: SUB_INT
> +; EG-DAG: AND_INT
> +; EG-DAG: ASHR
> +; EG-DAG: AND_INT
> +; EG-DAG: OR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHL
> +; EG-DAG: LSHL
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHR
> +; EG-DAG: LSHR
> +; EG-DAG: SETGT_UINT
> +; EG-DAG: SETGT_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: CNDGE_INT
> +; EG-DAG: CNDGE_INT
> +; EG-DAG: AND_INT
> +; EG-DAG: LSHR
> +; EG-DAG: SUB_INT
> +; EG-DAG: AND_INT
> +; EG-DAG: ASHR
> +; EG-DAG: AND_INT
> +; EG-DAG: OR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHL
> +; EG-DAG: LSHL
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHR
> +; EG-DAG: LSHR
> +; EG-DAG: SETGT_UINT
> +; EG-DAG: SETGT_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: CNDGE_INT
> +; EG-DAG: CNDGE_INT
> +; EG-DAG: AND_INT
> +; EG-DAG: LSHR
> +; EG-DAG: SUB_INT
> +; EG-DAG: AND_INT
> +; EG-DAG: ASHR
> +; EG-DAG: AND_INT
> +; EG-DAG: OR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHL
> +; EG-DAG: LSHL
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHR
> +; EG-DAG: LSHR
> +; EG-DAG: SETGT_UINT
> +; EG-DAG: SETGT_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: CNDGE_INT
> +; EG-DAG: CNDGE_INT
> +; EG-DAG: AND_INT
> +; EG-DAG: LSHR
> +; EG-DAG: SUB_INT
> +; EG-DAG: AND_INT
> +; EG-DAG: ASHR
> +; EG-DAG: AND_INT
> +; EG-DAG: OR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHL
> +; EG-DAG: LSHL
> +; EG-DAG: SUB_INT
> +; EG-DAG: LSHR
> +; EG-DAG: LSHR
> +; EG-DAG: SETGT_UINT
> +; EG-DAG: SETGT_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: XOR_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: SUB_INT
> +; EG-DAG: CNDGE_INT
> +; EG-DAG: CNDGE_INT
> +
> +; SI: S_ENDPGM
> +define void @fp_to_uint_v4i64(<4 x i64> addrspace(1)* %out, <4 x float> %x) {
> +  %conv = fptoui <4 x float> %x to <4 x i64>
> +  store <4 x i64> %conv, <4 x i64> addrspace(1)* %out
> +  ret void
> +}
> -- 
> 1.9.3
> 
> _______________________________________________
> 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