blob: e97e1d2a8dd80bdd40ce058179a346348634fa8f [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
; RUN: llc < %s -mtriple=amdgpu9.42-amd-amdhsa | FileCheck -check-prefix=GFX942 %s
; gfx942 has fp8 conversion instructions, but for the FNUZ formats rather than
; OCP, so an OCP conversion must not select them and uses the generic expansion
; instead. The subtargets with the OCP formats are covered by
; float-to-arbitrary-fp-fp8-hw.ll.
define i8 @to_fp8_f32(float %x) {
; GFX942-LABEL: to_fp8_f32:
; GFX942: ; %bb.0:
; GFX942-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX942-NEXT: v_frexp_exp_i32_f32_e32 v3, v0
; GFX942-NEXT: v_frexp_mant_f32_e32 v1, v0
; GFX942-NEXT: v_sub_u32_e32 v4, 15, v3
; GFX942-NEXT: v_and_b32_e32 v2, 0x7fffff, v1
; GFX942-NEXT: v_min_u32_e32 v4, 31, v4
; GFX942-NEXT: v_or_b32_e32 v2, 0x800000, v2
; GFX942-NEXT: v_sub_u32_e64 v6, v4, 1 clamp
; GFX942-NEXT: v_bfe_u32 v7, v2, 0, v6
; GFX942-NEXT: v_cmp_ne_u32_e32 vcc, 0, v7
; GFX942-NEXT: v_lshrrev_b32_e32 v5, v4, v2
; GFX942-NEXT: v_lshrrev_b32_e32 v2, v6, v2
; GFX942-NEXT: v_cndmask_b32_e64 v7, 0, 1, vcc
; GFX942-NEXT: v_and_or_b32 v7, v5, 1, v7
; GFX942-NEXT: v_and_b32_e32 v2, v2, v7
; GFX942-NEXT: v_cmp_ne_u32_e32 vcc, 0, v4
; GFX942-NEXT: s_movk_i32 s0, 0x80
; GFX942-NEXT: v_bfe_u32 v6, v1, 20, 3
; GFX942-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
; GFX942-NEXT: v_add_u32_e32 v2, v5, v2
; GFX942-NEXT: v_cmp_lt_i32_e32 vcc, 7, v2
; GFX942-NEXT: v_and_b32_sdwa v5, v0, s0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
; GFX942-NEXT: s_nop 0
; GFX942-NEXT: v_cndmask_b32_e64 v2, v2, 0, vcc
; GFX942-NEXT: v_cndmask_b32_e64 v4, 0, 8, vcc
; GFX942-NEXT: v_or3_b32 v2, v5, v4, v2
; GFX942-NEXT: v_and_b32_e32 v4, 0x7ffff, v1
; GFX942-NEXT: v_cmp_ne_u32_e32 vcc, 0, v4
; GFX942-NEXT: v_lshrrev_b32_e32 v1, 19, v1
; GFX942-NEXT: s_nop 0
; GFX942-NEXT: v_cndmask_b32_e64 v4, 0, 1, vcc
; GFX942-NEXT: v_and_or_b32 v4, v6, 1, v4
; GFX942-NEXT: v_and_b32_e32 v1, v1, v4
; GFX942-NEXT: v_add_u32_e32 v1, v6, v1
; GFX942-NEXT: v_cmp_lt_i32_e32 vcc, 7, v1
; GFX942-NEXT: s_nop 1
; GFX942-NEXT: v_cndmask_b32_e64 v1, v1, 0, vcc
; GFX942-NEXT: v_addc_co_u32_e32 v3, vcc, 6, v3, vcc
; GFX942-NEXT: v_lshlrev_b32_e32 v4, 3, v3
; GFX942-NEXT: v_or3_b32 v1, v5, v4, v1
; GFX942-NEXT: v_cmp_gt_i32_e32 vcc, 1, v3
; GFX942-NEXT: s_nop 1
; GFX942-NEXT: v_cndmask_b32_e32 v1, v1, v2, vcc
; GFX942-NEXT: v_cmp_eq_f32_e32 vcc, 0, v0
; GFX942-NEXT: v_mov_b32_e32 v2, 0x7f
; GFX942-NEXT: s_nop 0
; GFX942-NEXT: v_cndmask_b32_e32 v1, v1, v5, vcc
; GFX942-NEXT: v_cmp_o_f32_e32 vcc, v0, v0
; GFX942-NEXT: s_nop 1
; GFX942-NEXT: v_cndmask_b32_e32 v0, v2, v1, vcc
; GFX942-NEXT: s_setpc_b64 s[30:31]
%r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float %x, metadata !"Float8E4M3FN", metadata !"round.tonearest", i1 false)
ret i8 %r
}
define i8 @to_bf8_f32(float %x) {
; GFX942-LABEL: to_bf8_f32:
; GFX942: ; %bb.0:
; GFX942-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX942-NEXT: v_frexp_exp_i32_f32_e32 v3, v0
; GFX942-NEXT: v_frexp_mant_f32_e32 v1, v0
; GFX942-NEXT: v_sub_u32_e32 v4, 8, v3
; GFX942-NEXT: v_and_b32_e32 v2, 0x7fffff, v1
; GFX942-NEXT: v_min_u32_e32 v4, 31, v4
; GFX942-NEXT: v_or_b32_e32 v2, 0x800000, v2
; GFX942-NEXT: v_sub_u32_e64 v6, v4, 1 clamp
; GFX942-NEXT: v_bfe_u32 v7, v2, 0, v6
; GFX942-NEXT: v_cmp_ne_u32_e32 vcc, 0, v7
; GFX942-NEXT: v_lshrrev_b32_e32 v5, v4, v2
; GFX942-NEXT: v_lshrrev_b32_e32 v2, v6, v2
; GFX942-NEXT: v_cndmask_b32_e64 v7, 0, 1, vcc
; GFX942-NEXT: v_and_or_b32 v7, v5, 1, v7
; GFX942-NEXT: v_and_b32_e32 v2, v2, v7
; GFX942-NEXT: v_cmp_ne_u32_e32 vcc, 0, v4
; GFX942-NEXT: s_movk_i32 s0, 0x80
; GFX942-NEXT: v_bfe_u32 v6, v1, 21, 2
; GFX942-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
; GFX942-NEXT: v_add_u32_e32 v2, v5, v2
; GFX942-NEXT: v_cmp_lt_i32_e32 vcc, 3, v2
; GFX942-NEXT: v_and_b32_sdwa v5, v0, s0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:DWORD
; GFX942-NEXT: s_nop 0
; GFX942-NEXT: v_cndmask_b32_e64 v2, v2, 0, vcc
; GFX942-NEXT: v_cndmask_b32_e64 v4, 0, 4, vcc
; GFX942-NEXT: v_or3_b32 v2, v5, v4, v2
; GFX942-NEXT: v_and_b32_e32 v4, 0xfffff, v1
; GFX942-NEXT: v_cmp_ne_u32_e32 vcc, 0, v4
; GFX942-NEXT: v_lshrrev_b32_e32 v1, 20, v1
; GFX942-NEXT: s_nop 0
; GFX942-NEXT: v_cndmask_b32_e64 v4, 0, 1, vcc
; GFX942-NEXT: v_and_or_b32 v4, v6, 1, v4
; GFX942-NEXT: v_and_b32_e32 v1, v1, v4
; GFX942-NEXT: v_add_u32_e32 v1, v6, v1
; GFX942-NEXT: v_cmp_lt_i32_e32 vcc, 3, v1
; GFX942-NEXT: s_nop 1
; GFX942-NEXT: v_cndmask_b32_e64 v1, v1, 0, vcc
; GFX942-NEXT: v_addc_co_u32_e32 v3, vcc, 14, v3, vcc
; GFX942-NEXT: v_lshlrev_b32_e32 v4, 2, v3
; GFX942-NEXT: v_or3_b32 v4, v5, v4, v1
; GFX942-NEXT: v_cmp_gt_i32_e32 vcc, 1, v3
; GFX942-NEXT: v_cmp_eq_u32_e64 s[0:1], 30, v3
; GFX942-NEXT: s_nop 0
; GFX942-NEXT: v_cndmask_b32_e32 v2, v4, v2, vcc
; GFX942-NEXT: v_cmp_lt_i32_e32 vcc, 3, v1
; GFX942-NEXT: s_and_b64 s[0:1], s[0:1], vcc
; GFX942-NEXT: v_cmp_lt_i32_e32 vcc, 30, v3
; GFX942-NEXT: v_or_b32_e32 v1, 0x7c, v5
; GFX942-NEXT: s_or_b64 vcc, vcc, s[0:1]
; GFX942-NEXT: v_cndmask_b32_e32 v2, v2, v1, vcc
; GFX942-NEXT: v_cmp_eq_f32_e32 vcc, 0, v0
; GFX942-NEXT: s_movk_i32 s0, 0x204
; GFX942-NEXT: s_nop 0
; GFX942-NEXT: v_cndmask_b32_e32 v2, v2, v5, vcc
; GFX942-NEXT: v_cmp_class_f32_e64 vcc, v0, s0
; GFX942-NEXT: s_nop 1
; GFX942-NEXT: v_cndmask_b32_e32 v1, v2, v1, vcc
; GFX942-NEXT: v_mov_b32_e32 v2, 0x7e
; GFX942-NEXT: v_cmp_o_f32_e32 vcc, v0, v0
; GFX942-NEXT: s_nop 1
; GFX942-NEXT: v_cndmask_b32_e32 v0, v2, v1, vcc
; GFX942-NEXT: s_setpc_b64 s[30:31]
%r = call i8 @llvm.convert.to.arbitrary.fp.i8.f32(float %x, metadata !"Float8E5M2", metadata !"round.tonearest", i1 false)
ret i8 %r
}