Index: lib/Target/AMDGPU/AMDGPUISelLowering.cpp =================================================================== --- lib/Target/AMDGPU/AMDGPUISelLowering.cpp +++ lib/Target/AMDGPU/AMDGPUISelLowering.cpp @@ -2505,15 +2505,30 @@ SDValue AMDGPUTargetLowering::LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const { - assert(Op.getOperand(0).getValueType() == MVT::i64 && - "operation should be legal"); - // TODO: Factor out code common with LowerSINT_TO_FP. - EVT DestVT = Op.getValueType(); + SDValue Src = Op.getOperand(0); + EVT SrcVT = Src.getValueType(); + + if (SrcVT == MVT::i16) { + if (DestVT == MVT::f16) + return Op; + + if (DestVT == MVT::f32) { + SDLoc DL(Op); + + // Promote src to i32 + SDValue Ext = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i32, Src); + return DAG.getNode(ISD::UINT_TO_FP, DL, DestVT, Ext); + } + + return SDValue(); + } + + assert(SrcVT == MVT::i64 && "operation should be legal"); + if (Subtarget->has16BitInsts() && DestVT == MVT::f16) { SDLoc DL(Op); - SDValue Src = Op.getOperand(0); SDValue IntToFp32 = DAG.getNode(Op.getOpcode(), DL, MVT::f32, Src); SDValue FPRoundFlag = DAG.getIntPtrConstant(0, SDLoc(Op)); @@ -2532,12 +2547,30 @@ SDValue AMDGPUTargetLowering::LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) const { - assert(Op.getOperand(0).getValueType() == MVT::i64 && - "operation should be legal"); + EVT DestVT = Op.getValueType(); + + SDValue Src = Op.getOperand(0); + EVT SrcVT = Src.getValueType(); + + if (SrcVT == MVT::i16) { + if (DestVT == MVT::f16) + return Op; + + if (DestVT == MVT::f32) { + SDLoc DL(Op); + + // Promote src to i32 + SDValue Ext = DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i32, Src); + return DAG.getNode(ISD::SINT_TO_FP, DL, DestVT, Ext); + } + + return SDValue(); + } + + assert(SrcVT == MVT::i64 && "operation should be legal"); // TODO: Factor out code common with LowerUINT_TO_FP. - EVT DestVT = Op.getValueType(); if (Subtarget->has16BitInsts() && DestVT == MVT::f16) { SDLoc DL(Op); SDValue Src = Op.getOperand(0); Index: lib/Target/AMDGPU/SIISelLowering.cpp =================================================================== --- lib/Target/AMDGPU/SIISelLowering.cpp +++ lib/Target/AMDGPU/SIISelLowering.cpp @@ -471,8 +471,6 @@ setOperationAction(ISD::FP_TO_SINT, MVT::i16, Promote); setOperationAction(ISD::FP_TO_UINT, MVT::i16, Promote); - setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote); - setOperationAction(ISD::UINT_TO_FP, MVT::i16, Promote); // F16 - Constant Actions. setOperationAction(ISD::ConstantFP, MVT::f16, Legal); @@ -487,6 +485,10 @@ setOperationAction(ISD::FP_ROUND, MVT::f16, Custom); setOperationAction(ISD::FCOS, MVT::f16, Promote); setOperationAction(ISD::FSIN, MVT::f16, Promote); + + setOperationAction(ISD::SINT_TO_FP, MVT::i16, Custom); + setOperationAction(ISD::UINT_TO_FP, MVT::i16, Custom); + setOperationAction(ISD::FP_TO_SINT, MVT::f16, Promote); setOperationAction(ISD::FP_TO_UINT, MVT::f16, Promote); setOperationAction(ISD::SINT_TO_FP, MVT::f16, Promote); Index: test/CodeGen/AMDGPU/sdwa-peephole.ll =================================================================== --- test/CodeGen/AMDGPU/sdwa-peephole.ll +++ test/CodeGen/AMDGPU/sdwa-peephole.ll @@ -368,15 +368,15 @@ } ; GCN-LABEL: {{^}}sitofp_v2i16_to_v2f16: -; NOSDWA-DAG: v_bfe_i32 v{{[0-9]+}}, v{{[0-9]+}}, 0, 16 -; NOSDWA-DAG: v_ashrrev_i32_e32 v{{[0-9]+}}, 16, v{{[0-9]+}} -; NOSDWA-DAG: v_cvt_f32_i32_e32 v{{[0-9]+}}, v{{[0-9]+}} -; NOSDWA-DAG: v_cvt_f32_i32_e32 v{{[0-9]+}}, v{{[0-9]+}} -; NOSDWA-NOT: v_cvt_f32_i32_sdwa +; NOSDWA-DAG: v_cvt_f16_i16_e32 v{{[0-9]+}}, v{{[0-9]+}} +; NOSDWA-DAG: v_lshrrev_b32_e32 v{{[0-9]+}}, 16, v{{[0-9]+}} +; NOSDWA-DAG: v_cvt_f16_i16_e32 v{{[0-9]+}}, v{{[0-9]+}} +; NOSDWA-NOT: v_cvt_f16_i16_sdwa -; SDWA-DAG: v_cvt_f32_i32_sdwa v{{[0-9]+}}, sext(v{{[0-9]+}}) dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 -; SDWA-DAG: v_cvt_f32_i32_sdwa v{{[0-9]+}}, sext(v{{[0-9]+}}) dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1 +; SDWA-DAG: v_cvt_f16_i16_e32 v{{[0-9]+}}, v{{[0-9]+}} +; SDWA-DAG: v_cvt_f16_i16_sdwa v{{[0-9]+}}, v{{[0-9]+}} dst_sel:{{(WORD_1|DWORD)?}} dst_unused:UNUSED_PAD src0_sel:WORD_1 +; FIXME: Should be able to avoid or define amdgpu_kernel void @sitofp_v2i16_to_v2f16( <2 x half> addrspace(1)* %r, <2 x i16> addrspace(1)* %a) { Index: test/CodeGen/AMDGPU/sitofp.f16.ll =================================================================== --- test/CodeGen/AMDGPU/sitofp.f16.ll +++ test/CodeGen/AMDGPU/sitofp.f16.ll @@ -3,8 +3,12 @@ ; GCN-LABEL: {{^}}sitofp_i16_to_f16 ; GCN: buffer_load_{{sshort|ushort}} v[[A_I16:[0-9]+]] -; GCN: v_cvt_f32_i32_e32 v[[A_F32:[0-9]+]], v[[A_I16]] -; GCN: v_cvt_f16_f32_e32 v[[R_F16:[0-9]+]], v[[A_F32]] + +; SI: v_cvt_f32_i32_e32 v[[A_F32:[0-9]+]], v[[A_I16]] +; SI: v_cvt_f16_f32_e32 v[[R_F16:[0-9]+]], v[[A_F32]] + +; VI: v_cvt_f16_i16_e32 v[[R_F16:[0-9]+]], v[[A_I16]] + ; GCN: buffer_store_short v[[R_F16]] ; GCN: s_endpgm define amdgpu_kernel void @sitofp_i16_to_f16( @@ -45,10 +49,8 @@ ; SI-DAG: v_lshlrev_b32_e32 ; SI: v_or_b32_e32 -; VI-DAG: v_cvt_f32_i32_sdwa -; VI-DAG: v_cvt_f32_i32_sdwa -; VI-DAG: v_cvt_f16_f32_e32 -; VI-DAG: v_cvt_f16_f32_sdwa +; VI-DAG: v_cvt_f16_i16_sdwa v{{[0-9]+}}, v{{[0-9]+}} dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:WORD_1 +; VI-DAG: v_cvt_f16_i16_e32 ; VI: v_or_b32_e32 ; GCN: buffer_store_dword Index: test/CodeGen/AMDGPU/uitofp.f16.ll =================================================================== --- test/CodeGen/AMDGPU/uitofp.f16.ll +++ test/CodeGen/AMDGPU/uitofp.f16.ll @@ -4,8 +4,10 @@ ; GCN-LABEL: {{^}}uitofp_i16_to_f16 ; GCN: buffer_load_ushort v[[A_I16:[0-9]+]] ; SI: v_cvt_f32_u32_e32 v[[A_F32:[0-9]+]], v[[A_I16]] -; VI: v_cvt_f32_i32_e32 v[[A_F32:[0-9]+]], v[[A_I16]] -; GCN: v_cvt_f16_f32_e32 v[[R_F16:[0-9]+]], v[[A_F32]] +; SI: v_cvt_f16_f32_e32 v[[R_F16:[0-9]+]], v[[A_F32]] + +; VI: v_cvt_f16_u16_e32 v[[R_F16:[0-9]+]], v[[A_I16]] + ; GCN: buffer_store_short v[[R_F16]] ; GCN: s_endpgm define amdgpu_kernel void @uitofp_i16_to_f16( @@ -46,10 +48,9 @@ ; SI-DAG: v_lshlrev_b32_e32 ; SI: v_or_b32_e32 -; VI-DAG: v_cvt_f16_f32_e32 -; VI-DAG: v_cvt_f32_i32_sdwa -; VI-DAG: v_cvt_f32_i32_sdwa -; VI-DAG: v_cvt_f16_f32_sdwa + +; VI-DAG: v_cvt_f16_u16_e32 +; VI-DAG: v_cvt_f16_u16_sdwa v{{[0-9]+}}, v{{[0-9]+}} dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:WORD_1 ; VI: v_or_b32_e32 ; GCN: buffer_store_dword