blob: 8ac7aa84b31e8ba050803dd83f38522213dc7938 [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
; RUN: llc -mtriple=amdgpu9.50 < %s | FileCheck --check-prefixes=GFX950 %s
; RUN: llc -mtriple=amdgpu12.50 -mattr=-real-true16 < %s | FileCheck --check-prefixes=GFX1250 %s
define amdgpu_ps void @strict_fptrunc_f32_to_bf16(float %a, ptr %out) #0 {
; GFX950-LABEL: strict_fptrunc_f32_to_bf16:
; GFX950: ; %bb.0:
; GFX950-NEXT: v_mov_b32_e32 v3, v2
; GFX950-NEXT: v_mov_b32_e32 v2, v1
; GFX950-NEXT: v_cvt_pk_bf16_f32 v0, v0, s0
; GFX950-NEXT: flat_store_short v[2:3], v0
; GFX950-NEXT: s_endpgm
;
; GFX1250-LABEL: strict_fptrunc_f32_to_bf16:
; GFX1250: ; %bb.0:
; GFX1250-NEXT: global_wb
; GFX1250-NEXT: v_nop
; GFX1250-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
; GFX1250-NEXT: v_dual_mov_b32 v3, v2 :: v_dual_mov_b32 v2, v1
; GFX1250-NEXT: v_cvt_pk_bf16_f32 v0, v0, s0
; GFX1250-NEXT: flat_store_b16 v[2:3], v0
; GFX1250-NEXT: s_endpgm
%cvt = call bfloat @llvm.experimental.constrained.fptrunc.bf16.f32(float %a, metadata !"round.tonearest", metadata !"fpexcept.strict")
store bfloat %cvt, ptr %out
ret void
}
define amdgpu_ps void @strict_fptrunc_f64_to_bf16(double %a, ptr %out) #0 {
; GFX950-LABEL: strict_fptrunc_f64_to_bf16:
; GFX950: ; %bb.0:
; GFX950-NEXT: v_cvt_f32_f64_e32 v6, v[0:1]
; GFX950-NEXT: v_cvt_f64_f32_e32 v[4:5], v6
; GFX950-NEXT: v_and_b32_e32 v7, 1, v6
; GFX950-NEXT: v_cmp_gt_f64_e64 s[2:3], |v[0:1]|, |v[4:5]|
; GFX950-NEXT: v_cmp_nlg_f64_e32 vcc, v[0:1], v[4:5]
; GFX950-NEXT: v_cmp_eq_u32_e64 s[0:1], 1, v7
; GFX950-NEXT: v_cndmask_b32_e64 v0, -1, 1, s[2:3]
; GFX950-NEXT: v_add_u32_e32 v0, v6, v0
; GFX950-NEXT: s_or_b64 vcc, vcc, s[0:1]
; GFX950-NEXT: v_cndmask_b32_e32 v0, v0, v6, vcc
; GFX950-NEXT: v_cvt_pk_bf16_f32 v0, v0, s0
; GFX950-NEXT: flat_store_short v[2:3], v0
; GFX950-NEXT: s_endpgm
;
; GFX1250-LABEL: strict_fptrunc_f64_to_bf16:
; GFX1250: ; %bb.0:
; GFX1250-NEXT: global_wb
; GFX1250-NEXT: v_nop
; GFX1250-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
; GFX1250-NEXT: v_cvt_f32_f64_e32 v6, v[0:1]
; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
; GFX1250-NEXT: v_cvt_f64_f32_e32 v[4:5], v6
; GFX1250-NEXT: v_cmp_gt_f64_e64 s0, |v[0:1]|, |v[4:5]|
; GFX1250-NEXT: v_cmp_nlg_f64_e32 vcc_lo, v[0:1], v[4:5]
; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
; GFX1250-NEXT: v_cndmask_b32_e64 v0, -1, 1, s0
; GFX1250-NEXT: v_dual_add_nc_u32 v0, v6, v0 :: v_dual_bitop2_b32 v7, 1, v6 bitop3:0x40
; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_1)
; GFX1250-NEXT: v_cmp_eq_u32_e64 s0, 1, v7
; GFX1250-NEXT: s_or_b32 vcc_lo, vcc_lo, s0
; GFX1250-NEXT: v_cndmask_b32_e32 v0, v0, v6, vcc_lo
; GFX1250-NEXT: v_cvt_pk_bf16_f32 v0, v0, s0
; GFX1250-NEXT: flat_store_b16 v[2:3], v0
; GFX1250-NEXT: s_endpgm
%cvt = call bfloat @llvm.experimental.constrained.fptrunc.bf16.f64(double %a, metadata !"round.tonearest", metadata !"fpexcept.strict")
store bfloat %cvt, ptr %out
ret void
}
define amdgpu_ps void @strict_fptrunc_v2f32_to_v2bf16(<2 x float> %a, ptr %out) #0 {
; GFX950-LABEL: strict_fptrunc_v2f32_to_v2bf16:
; GFX950: ; %bb.0:
; GFX950-NEXT: v_cvt_pk_bf16_f32 v0, v0, v1
; GFX950-NEXT: flat_store_dword v[2:3], v0
; GFX950-NEXT: s_endpgm
;
; GFX1250-LABEL: strict_fptrunc_v2f32_to_v2bf16:
; GFX1250: ; %bb.0:
; GFX1250-NEXT: global_wb
; GFX1250-NEXT: v_nop
; GFX1250-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
; GFX1250-NEXT: v_cvt_pk_bf16_f32 v0, v0, v1
; GFX1250-NEXT: flat_store_b32 v[2:3], v0
; GFX1250-NEXT: s_endpgm
%cvt = call <2 x bfloat> @llvm.experimental.constrained.fptrunc.v2bf16.v2f32(<2 x float> %a, metadata !"round.tonearest", metadata !"fpexcept.strict")
store <2 x bfloat> %cvt, ptr %out
ret void
}
define amdgpu_ps void @strict_fptrunc_v2f64_to_v2bf16(<2 x double> %a, ptr %out) #0 {
; GFX950-LABEL: strict_fptrunc_v2f64_to_v2bf16:
; GFX950: ; %bb.0:
; GFX950-NEXT: v_cvt_f32_f64_e32 v8, v[2:3]
; GFX950-NEXT: v_and_b32_e32 v6, 1, v8
; GFX950-NEXT: v_cmp_ne_u32_e32 vcc, 0, v6
; GFX950-NEXT: v_cvt_f64_f32_e32 v[6:7], v8
; GFX950-NEXT: v_cmp_gt_f64_e64 s[2:3], |v[2:3]|, |v[6:7]|
; GFX950-NEXT: v_cmp_nlg_f64_e64 s[0:1], v[2:3], v[6:7]
; GFX950-NEXT: v_cvt_f32_f64_e32 v9, v[0:1]
; GFX950-NEXT: v_cndmask_b32_e64 v2, -1, 1, s[2:3]
; GFX950-NEXT: v_add_u32_e32 v2, v8, v2
; GFX950-NEXT: s_or_b64 vcc, vcc, s[0:1]
; GFX950-NEXT: v_cndmask_b32_e32 v6, v2, v8, vcc
; GFX950-NEXT: v_cvt_f64_f32_e32 v[2:3], v9
; GFX950-NEXT: v_and_b32_e32 v10, 1, v9
; GFX950-NEXT: v_cmp_gt_f64_e64 s[2:3], |v[0:1]|, |v[2:3]|
; GFX950-NEXT: v_cmp_ne_u32_e32 vcc, 0, v10
; GFX950-NEXT: v_cmp_nlg_f64_e64 s[0:1], v[0:1], v[2:3]
; GFX950-NEXT: v_cndmask_b32_e64 v0, -1, 1, s[2:3]
; GFX950-NEXT: v_add_u32_e32 v0, v9, v0
; GFX950-NEXT: s_or_b64 vcc, vcc, s[0:1]
; GFX950-NEXT: v_cndmask_b32_e32 v0, v0, v9, vcc
; GFX950-NEXT: v_cvt_pk_bf16_f32 v0, v0, v6
; GFX950-NEXT: flat_store_dword v[4:5], v0
; GFX950-NEXT: s_endpgm
;
; GFX1250-LABEL: strict_fptrunc_v2f64_to_v2bf16:
; GFX1250: ; %bb.0:
; GFX1250-NEXT: global_wb
; GFX1250-NEXT: v_nop
; GFX1250-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
; GFX1250-NEXT: v_cvt_f32_f64_e32 v10, v[2:3]
; GFX1250-NEXT: v_cvt_f32_f64_e32 v11, v[0:1]
; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
; GFX1250-NEXT: v_cvt_f64_f32_e32 v[6:7], v10
; GFX1250-NEXT: v_cvt_f64_f32_e32 v[8:9], v11
; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_1) | instid1(VALU_DEP_3)
; GFX1250-NEXT: v_cmp_gt_f64_e64 s1, |v[2:3]|, |v[6:7]|
; GFX1250-NEXT: v_cmp_nlg_f64_e32 vcc_lo, v[2:3], v[6:7]
; GFX1250-NEXT: v_cmp_nlg_f64_e64 s0, v[0:1], v[8:9]
; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_2)
; GFX1250-NEXT: v_cndmask_b32_e64 v2, -1, 1, s1
; GFX1250-NEXT: v_cmp_gt_f64_e64 s1, |v[0:1]|, |v[8:9]|
; GFX1250-NEXT: v_dual_add_nc_u32 v1, v10, v2 :: v_dual_bitop2_b32 v13, 1, v11 bitop3:0x40
; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_3)
; GFX1250-NEXT: v_cmp_ne_u32_e64 s2, 0, v13
; GFX1250-NEXT: v_cndmask_b32_e64 v0, -1, 1, s1
; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
; GFX1250-NEXT: v_dual_add_nc_u32 v0, v11, v0 :: v_dual_bitop2_b32 v12, 1, v10 bitop3:0x40
; GFX1250-NEXT: v_cmp_ne_u32_e64 s1, 0, v12
; GFX1250-NEXT: s_or_b32 vcc_lo, s1, vcc_lo
; GFX1250-NEXT: v_cndmask_b32_e32 v1, v1, v10, vcc_lo
; GFX1250-NEXT: s_or_b32 vcc_lo, s2, s0
; GFX1250-NEXT: v_cndmask_b32_e32 v0, v0, v11, vcc_lo
; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1)
; GFX1250-NEXT: v_cvt_pk_bf16_f32 v0, v0, v1
; GFX1250-NEXT: flat_store_b32 v[4:5], v0
; GFX1250-NEXT: s_endpgm
%cvt = call <2 x bfloat> @llvm.experimental.constrained.fptrunc.v2bf16.v2f64(<2 x double> %a, metadata !"round.tonearest", metadata !"fpexcept.strict")
store <2 x bfloat> %cvt, ptr %out
ret void
}
declare bfloat @llvm.experimental.constrained.fptrunc.bf16.f32(float, metadata, metadata)
declare bfloat @llvm.experimental.constrained.fptrunc.bf16.f64(double, metadata, metadata)
declare <2 x bfloat> @llvm.experimental.constrained.fptrunc.v2bf16.v2f32(<2 x float>, metadata, metadata)
declare <2 x bfloat> @llvm.experimental.constrained.fptrunc.v2bf16.v2f64(<2 x double>, metadata, metadata)
attributes #0 = { strictfp }