Index: llvm/trunk/include/llvm/IR/IntrinsicsAMDGPU.td =================================================================== --- llvm/trunk/include/llvm/IR/IntrinsicsAMDGPU.td +++ llvm/trunk/include/llvm/IR/IntrinsicsAMDGPU.td @@ -181,7 +181,7 @@ >; def int_amdgcn_frexp_exp : Intrinsic< - [llvm_i32_ty], [llvm_anyfloat_ty], [IntrNoMem] + [llvm_anyint_ty], [llvm_anyfloat_ty], [IntrNoMem] >; // v_fract is buggy on SI/CI. It mishandles infinities, may return 1.0 Index: llvm/trunk/lib/Target/AMDGPU/SIInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/AMDGPU/SIInstrInfo.td +++ llvm/trunk/lib/Target/AMDGPU/SIInstrInfo.td @@ -959,7 +959,6 @@ def VOP_F64_F32 : VOPProfile <[f64, f32, untyped, untyped]>; def VOP_F64_F64 : VOPProfile <[f64, f64, untyped, untyped]>; def VOP_F64_I32 : VOPProfile <[f64, i32, untyped, untyped]>; -def VOP_I32_F16 : VOPProfile <[i32, f16, untyped, untyped]>; def VOP_I32_F32 : VOPProfile <[i32, f32, untyped, untyped]>; def VOP_I32_F64 : VOPProfile <[i32, f64, untyped, untyped]>; def VOP_I32_I32 : VOPProfile <[i32, i32, untyped, untyped]>; Index: llvm/trunk/lib/Target/AMDGPU/VOP1Instructions.td =================================================================== --- llvm/trunk/lib/Target/AMDGPU/VOP1Instructions.td +++ llvm/trunk/lib/Target/AMDGPU/VOP1Instructions.td @@ -290,7 +290,7 @@ defm V_LOG_F16 : VOP1Inst <"v_log_f16", VOP_F16_F16, flog2>; defm V_EXP_F16 : VOP1Inst <"v_exp_f16", VOP_F16_F16, fexp2>; defm V_FREXP_MANT_F16 : VOP1Inst <"v_frexp_mant_f16", VOP_F16_F16, int_amdgcn_frexp_mant>; -defm V_FREXP_EXP_I16_F16 : VOP1Inst <"v_frexp_exp_i16_f16", VOP_I32_F16, int_amdgcn_frexp_exp>; +defm V_FREXP_EXP_I16_F16 : VOP1Inst <"v_frexp_exp_i16_f16", VOP_I16_F16, int_amdgcn_frexp_exp>; defm V_FLOOR_F16 : VOP1Inst <"v_floor_f16", VOP_F16_F16, ffloor>; defm V_CEIL_F16 : VOP1Inst <"v_ceil_f16", VOP_F16_F16, fceil>; defm V_TRUNC_F16 : VOP1Inst <"v_trunc_f16", VOP_F16_F16, ftrunc>; Index: llvm/trunk/test/CodeGen/AMDGPU/llvm.amdgcn.frexp.exp.f16.ll =================================================================== --- llvm/trunk/test/CodeGen/AMDGPU/llvm.amdgcn.frexp.exp.f16.ll +++ llvm/trunk/test/CodeGen/AMDGPU/llvm.amdgcn.frexp.exp.f16.ll @@ -1,18 +1,49 @@ ; RUN: llc -march=amdgcn -mcpu=fiji -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=VI %s -declare i32 @llvm.amdgcn.frexp.exp.f16(half %a) +declare i16 @llvm.amdgcn.frexp.exp.i16.f16(half %a) ; GCN-LABEL: {{^}}frexp_exp_f16 ; GCN: buffer_load_ushort v[[A_F16:[0-9]+]] -; VI: v_frexp_exp_i16_f16_e32 v[[R_I16:[0-9]+]], v[[A_F16]] +; VI: v_frexp_exp_i16_f16_e32 v[[R_I16:[0-9]+]], v[[A_F16]] ; GCN: buffer_store_short v[[R_I16]] define void @frexp_exp_f16( i16 addrspace(1)* %r, half addrspace(1)* %a) { entry: %a.val = load half, half addrspace(1)* %a - %r.val = call i32 @llvm.amdgcn.frexp.exp.f16(half %a.val) - %r.val.i16 = trunc i32 %r.val to i16 - store i16 %r.val.i16, i16 addrspace(1)* %r + %r.val = call i16 @llvm.amdgcn.frexp.exp.i16.f16(half %a.val) + store i16 %r.val, i16 addrspace(1)* %r + ret void +} + +; GCN-LABEL: {{^}}frexp_exp_f16_sext +; GCN: buffer_load_ushort v[[A_F16:[0-9]+]] +; VI: v_frexp_exp_i16_f16_e32 v[[R_I16:[0-9]+]], v[[A_F16]] +; VI: v_bfe_i32 v[[R_I32:[0-9]+]], v[[R_I16]], 0, 16{{$}} +; GCN: buffer_store_dword v[[R_I32]] +define void @frexp_exp_f16_sext( + i32 addrspace(1)* %r, + half addrspace(1)* %a) { +entry: + %a.val = load half, half addrspace(1)* %a + %r.val = call i16 @llvm.amdgcn.frexp.exp.i16.f16(half %a.val) + %r.val.sext = sext i16 %r.val to i32 + store i32 %r.val.sext, i32 addrspace(1)* %r + ret void +} + +; GCN-LABEL: {{^}}frexp_exp_f16_zext +; GCN: buffer_load_ushort v[[A_F16:[0-9]+]] +; VI: v_frexp_exp_i16_f16_e32 v[[R_I16:[0-9]+]], v[[A_F16]] +; VI: v_and_b32_e32 v[[R_I32:[0-9]+]], 0xffff, v[[R_I16]] +; GCN: buffer_store_dword v[[R_I32]] +define void @frexp_exp_f16_zext( + i32 addrspace(1)* %r, + half addrspace(1)* %a) { +entry: + %a.val = load half, half addrspace(1)* %a + %r.val = call i16 @llvm.amdgcn.frexp.exp.i16.f16(half %a.val) + %r.val.zext = zext i16 %r.val to i32 + store i32 %r.val.zext, i32 addrspace(1)* %r ret void } Index: llvm/trunk/test/CodeGen/AMDGPU/llvm.amdgcn.frexp.exp.ll =================================================================== --- llvm/trunk/test/CodeGen/AMDGPU/llvm.amdgcn.frexp.exp.ll +++ llvm/trunk/test/CodeGen/AMDGPU/llvm.amdgcn.frexp.exp.ll @@ -3,13 +3,13 @@ declare float @llvm.fabs.f32(float) #0 declare double @llvm.fabs.f64(double) #0 -declare i32 @llvm.amdgcn.frexp.exp.f32(float) #0 -declare i32 @llvm.amdgcn.frexp.exp.f64(double) #0 +declare i32 @llvm.amdgcn.frexp.exp.i32.f32(float) #0 +declare i32 @llvm.amdgcn.frexp.exp.i32.f64(double) #0 ; GCN-LABEL: {{^}}s_test_frexp_exp_f32: ; GCN: v_frexp_exp_i32_f32_e32 {{v[0-9]+}}, {{s[0-9]+}} define void @s_test_frexp_exp_f32(i32 addrspace(1)* %out, float %src) #1 { - %frexp.exp = call i32 @llvm.amdgcn.frexp.exp.f32(float %src) + %frexp.exp = call i32 @llvm.amdgcn.frexp.exp.i32.f32(float %src) store i32 %frexp.exp, i32 addrspace(1)* %out ret void } @@ -18,7 +18,7 @@ ; GCN: v_frexp_exp_i32_f32_e64 {{v[0-9]+}}, |{{s[0-9]+}}| define void @s_test_fabs_frexp_exp_f32(i32 addrspace(1)* %out, float %src) #1 { %fabs.src = call float @llvm.fabs.f32(float %src) - %frexp.exp = call i32 @llvm.amdgcn.frexp.exp.f32(float %fabs.src) + %frexp.exp = call i32 @llvm.amdgcn.frexp.exp.i32.f32(float %fabs.src) store i32 %frexp.exp, i32 addrspace(1)* %out ret void } @@ -28,7 +28,7 @@ define void @s_test_fneg_fabs_frexp_exp_f32(i32 addrspace(1)* %out, float %src) #1 { %fabs.src = call float @llvm.fabs.f32(float %src) %fneg.fabs.src = fsub float -0.0, %fabs.src - %frexp.exp = call i32 @llvm.amdgcn.frexp.exp.f32(float %fneg.fabs.src) + %frexp.exp = call i32 @llvm.amdgcn.frexp.exp.i32.f32(float %fneg.fabs.src) store i32 %frexp.exp, i32 addrspace(1)* %out ret void } @@ -36,7 +36,7 @@ ; GCN-LABEL: {{^}}s_test_frexp_exp_f64: ; GCN: v_frexp_exp_i32_f64_e32 {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}} define void @s_test_frexp_exp_f64(i32 addrspace(1)* %out, double %src) #1 { - %frexp.exp = call i32 @llvm.amdgcn.frexp.exp.f64(double %src) + %frexp.exp = call i32 @llvm.amdgcn.frexp.exp.i32.f64(double %src) store i32 %frexp.exp, i32 addrspace(1)* %out ret void } @@ -45,7 +45,7 @@ ; GCN: v_frexp_exp_i32_f64_e64 {{v[0-9]+}}, |{{s\[[0-9]+:[0-9]+\]}}| define void @s_test_fabs_frexp_exp_f64(i32 addrspace(1)* %out, double %src) #1 { %fabs.src = call double @llvm.fabs.f64(double %src) - %frexp.exp = call i32 @llvm.amdgcn.frexp.exp.f64(double %fabs.src) + %frexp.exp = call i32 @llvm.amdgcn.frexp.exp.i32.f64(double %fabs.src) store i32 %frexp.exp, i32 addrspace(1)* %out ret void } @@ -55,7 +55,7 @@ define void @s_test_fneg_fabs_frexp_exp_f64(i32 addrspace(1)* %out, double %src) #1 { %fabs.src = call double @llvm.fabs.f64(double %src) %fneg.fabs.src = fsub double -0.0, %fabs.src - %frexp.exp = call i32 @llvm.amdgcn.frexp.exp.f64(double %fneg.fabs.src) + %frexp.exp = call i32 @llvm.amdgcn.frexp.exp.i32.f64(double %fneg.fabs.src) store i32 %frexp.exp, i32 addrspace(1)* %out ret void }