blob: b0627c3d4e77d1b53bb98e2cd2a1092af60ad3b5 [file] [log] [blame]
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc -mtriple=amdgcn < %s | FileCheck -check-prefix=GCN %s
; RUN: llc -mtriple=amdgcn -mcpu=tonga < %s | FileCheck -check-prefixes=VI %s
; RUN: llc -mtriple=amdgcn -mcpu=gfx900 < %s | FileCheck -check-prefixes=GFX9 %s
; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 < %s | FileCheck -check-prefixes=GFX11 %s
define half @bitcast_i16_to_f16(i16 %a, i32 %b) {
; GCN-LABEL: bitcast_i16_to_f16:
; GCN: ; %bb.0:
; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GCN-NEXT: v_and_b32_e32 v2, 0xffff, v0
; GCN-NEXT: v_cmp_ne_u32_e32 vcc, 0, v1
; GCN-NEXT: ; implicit-def: $vgpr0
; GCN-NEXT: s_and_saveexec_b64 s[4:5], vcc
; GCN-NEXT: s_xor_b64 s[4:5], exec, s[4:5]
; GCN-NEXT: s_cbranch_execnz .LBB0_3
; GCN-NEXT: ; %bb.1: ; %Flow
; GCN-NEXT: s_andn2_saveexec_b64 s[4:5], s[4:5]
; GCN-NEXT: s_cbranch_execnz .LBB0_4
; GCN-NEXT: .LBB0_2: ; %end
; GCN-NEXT: s_or_b64 exec, exec, s[4:5]
; GCN-NEXT: s_setpc_b64 s[30:31]
; GCN-NEXT: .LBB0_3: ; %cmp.false
; GCN-NEXT: v_cvt_f32_f16_e32 v0, v2
; GCN-NEXT: ; implicit-def: $vgpr2
; GCN-NEXT: s_andn2_saveexec_b64 s[4:5], s[4:5]
; GCN-NEXT: s_cbranch_execz .LBB0_2
; GCN-NEXT: .LBB0_4: ; %cmp.true
; GCN-NEXT: v_add_i32_e32 v0, vcc, 3, v2
; GCN-NEXT: v_cvt_f32_f16_e32 v0, v0
; GCN-NEXT: s_or_b64 exec, exec, s[4:5]
; GCN-NEXT: s_setpc_b64 s[30:31]
;
; VI-LABEL: bitcast_i16_to_f16:
; VI: ; %bb.0:
; VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; VI-NEXT: v_cmp_ne_u32_e32 vcc, 0, v1
; VI-NEXT: s_and_saveexec_b64 s[4:5], vcc
; VI-NEXT: s_xor_b64 s[4:5], exec, s[4:5]
; VI-NEXT: s_andn2_saveexec_b64 s[4:5], s[4:5]
; VI-NEXT: ; %bb.1: ; %cmp.true
; VI-NEXT: v_add_u16_e32 v0, 3, v0
; VI-NEXT: ; %bb.2: ; %end
; VI-NEXT: s_or_b64 exec, exec, s[4:5]
; VI-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: bitcast_i16_to_f16:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT: v_cmp_ne_u32_e32 vcc, 0, v1
; GFX9-NEXT: s_and_saveexec_b64 s[4:5], vcc
; GFX9-NEXT: s_xor_b64 s[4:5], exec, s[4:5]
; GFX9-NEXT: s_andn2_saveexec_b64 s[4:5], s[4:5]
; GFX9-NEXT: ; %bb.1: ; %cmp.true
; GFX9-NEXT: v_add_u16_e32 v0, 3, v0
; GFX9-NEXT: ; %bb.2: ; %end
; GFX9-NEXT: s_or_b64 exec, exec, s[4:5]
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-LABEL: bitcast_i16_to_f16:
; GFX11: ; %bb.0:
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX11-NEXT: s_mov_b32 s0, exec_lo
; GFX11-NEXT: v_cmpx_ne_u32_e32 0, v1
; GFX11-NEXT: s_xor_b32 s0, exec_lo, s0
; GFX11-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
; GFX11-NEXT: s_and_not1_saveexec_b32 s0, s0
; GFX11-NEXT: ; %bb.1: ; %cmp.true
; GFX11-NEXT: v_add_nc_u16 v0, v0, 3
; GFX11-NEXT: ; %bb.2: ; %end
; GFX11-NEXT: s_or_b32 exec_lo, exec_lo, s0
; GFX11-NEXT: s_setpc_b64 s[30:31]
%cmp = icmp eq i32 %b, 0
br i1 %cmp, label %cmp.true, label %cmp.false
cmp.true:
%a1 = add i16 %a, 3
%a2 = bitcast i16 %a1 to half
br label %end
cmp.false:
%a3 = bitcast i16 %a to half
br label %end
end:
%phi = phi half [ %a2, %cmp.true ], [ %a3, %cmp.false ]
ret half %phi
}
define i16 @bitcast_f16_to_i16(half %a, i32 %b) {
; GCN-LABEL: bitcast_f16_to_i16:
; GCN: ; %bb.0:
; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GCN-NEXT: v_cmp_ne_u32_e32 vcc, 0, v1
; GCN-NEXT: v_cvt_f16_f32_e32 v0, v0
; GCN-NEXT: s_and_saveexec_b64 s[4:5], vcc
; GCN-NEXT: s_xor_b64 s[4:5], exec, s[4:5]
; GCN-NEXT: s_andn2_saveexec_b64 s[4:5], s[4:5]
; GCN-NEXT: s_cbranch_execz .LBB1_2
; GCN-NEXT: ; %bb.1:
; GCN-NEXT: v_cvt_f32_f16_e32 v0, v0
; GCN-NEXT: v_add_f32_e32 v0, 0x38000000, v0
; GCN-NEXT: v_cvt_f16_f32_e32 v0, v0
; GCN-NEXT: .LBB1_2:
; GCN-NEXT: s_or_b64 exec, exec, s[4:5]
; GCN-NEXT: s_setpc_b64 s[30:31]
;
; VI-LABEL: bitcast_f16_to_i16:
; VI: ; %bb.0:
; VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; VI-NEXT: v_cmp_ne_u32_e32 vcc, 0, v1
; VI-NEXT: s_and_saveexec_b64 s[4:5], vcc
; VI-NEXT: s_xor_b64 s[4:5], exec, s[4:5]
; VI-NEXT: s_andn2_saveexec_b64 s[4:5], s[4:5]
; VI-NEXT: ; %bb.1: ; %cmp.true
; VI-NEXT: v_add_f16_e32 v0, 0x200, v0
; VI-NEXT: ; %bb.2: ; %end
; VI-NEXT: s_or_b64 exec, exec, s[4:5]
; VI-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: bitcast_f16_to_i16:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT: v_cmp_ne_u32_e32 vcc, 0, v1
; GFX9-NEXT: s_and_saveexec_b64 s[4:5], vcc
; GFX9-NEXT: s_xor_b64 s[4:5], exec, s[4:5]
; GFX9-NEXT: s_andn2_saveexec_b64 s[4:5], s[4:5]
; GFX9-NEXT: ; %bb.1: ; %cmp.true
; GFX9-NEXT: v_add_f16_e32 v0, 0x200, v0
; GFX9-NEXT: ; %bb.2: ; %end
; GFX9-NEXT: s_or_b64 exec, exec, s[4:5]
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-LABEL: bitcast_f16_to_i16:
; GFX11: ; %bb.0:
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX11-NEXT: s_mov_b32 s0, exec_lo
; GFX11-NEXT: v_cmpx_ne_u32_e32 0, v1
; GFX11-NEXT: s_xor_b32 s0, exec_lo, s0
; GFX11-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
; GFX11-NEXT: s_and_not1_saveexec_b32 s0, s0
; GFX11-NEXT: ; %bb.1: ; %cmp.true
; GFX11-NEXT: v_add_f16_e32 v0, 0x200, v0
; GFX11-NEXT: ; %bb.2: ; %end
; GFX11-NEXT: s_or_b32 exec_lo, exec_lo, s0
; GFX11-NEXT: s_setpc_b64 s[30:31]
%cmp = icmp eq i32 %b, 0
br i1 %cmp, label %cmp.true, label %cmp.false
cmp.true:
%a1 = fadd half %a, 0xH0200
%a2 = bitcast half %a1 to i16
br label %end
cmp.false:
%a3 = bitcast half %a to i16
br label %end
end:
%phi = phi i16 [ %a2, %cmp.true ], [ %a3, %cmp.false ]
ret i16 %phi
}
define bfloat @bitcast_i16_to_bf16(i16 %a, i32 %b) {
; GCN-LABEL: bitcast_i16_to_bf16:
; GCN: ; %bb.0:
; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GCN-NEXT: v_and_b32_e32 v0, 0xffff, v0
; GCN-NEXT: v_cmp_ne_u32_e32 vcc, 0, v1
; GCN-NEXT: v_lshlrev_b32_e32 v0, 16, v0
; GCN-NEXT: s_and_saveexec_b64 s[4:5], vcc
; GCN-NEXT: s_xor_b64 s[4:5], exec, s[4:5]
; GCN-NEXT: s_andn2_saveexec_b64 s[4:5], s[4:5]
; GCN-NEXT: s_cbranch_execz .LBB2_2
; GCN-NEXT: ; %bb.1: ; %cmp.true
; GCN-NEXT: v_add_i32_e32 v0, vcc, 0x30000, v0
; GCN-NEXT: .LBB2_2: ; %end
; GCN-NEXT: s_or_b64 exec, exec, s[4:5]
; GCN-NEXT: s_setpc_b64 s[30:31]
;
; VI-LABEL: bitcast_i16_to_bf16:
; VI: ; %bb.0:
; VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; VI-NEXT: v_cmp_ne_u32_e32 vcc, 0, v1
; VI-NEXT: s_and_saveexec_b64 s[4:5], vcc
; VI-NEXT: s_xor_b64 s[4:5], exec, s[4:5]
; VI-NEXT: s_andn2_saveexec_b64 s[4:5], s[4:5]
; VI-NEXT: ; %bb.1: ; %cmp.true
; VI-NEXT: v_add_u16_e32 v0, 3, v0
; VI-NEXT: ; %bb.2: ; %end
; VI-NEXT: s_or_b64 exec, exec, s[4:5]
; VI-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: bitcast_i16_to_bf16:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT: v_cmp_ne_u32_e32 vcc, 0, v1
; GFX9-NEXT: s_and_saveexec_b64 s[4:5], vcc
; GFX9-NEXT: s_xor_b64 s[4:5], exec, s[4:5]
; GFX9-NEXT: s_andn2_saveexec_b64 s[4:5], s[4:5]
; GFX9-NEXT: ; %bb.1: ; %cmp.true
; GFX9-NEXT: v_add_u16_e32 v0, 3, v0
; GFX9-NEXT: ; %bb.2: ; %end
; GFX9-NEXT: s_or_b64 exec, exec, s[4:5]
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-LABEL: bitcast_i16_to_bf16:
; GFX11: ; %bb.0:
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX11-NEXT: s_mov_b32 s0, exec_lo
; GFX11-NEXT: v_cmpx_ne_u32_e32 0, v1
; GFX11-NEXT: s_xor_b32 s0, exec_lo, s0
; GFX11-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
; GFX11-NEXT: s_and_not1_saveexec_b32 s0, s0
; GFX11-NEXT: ; %bb.1: ; %cmp.true
; GFX11-NEXT: v_add_nc_u16 v0, v0, 3
; GFX11-NEXT: ; %bb.2: ; %end
; GFX11-NEXT: s_or_b32 exec_lo, exec_lo, s0
; GFX11-NEXT: s_setpc_b64 s[30:31]
%cmp = icmp eq i32 %b, 0
br i1 %cmp, label %cmp.true, label %cmp.false
cmp.true:
%a1 = add i16 %a, 3
%a2 = bitcast i16 %a1 to bfloat
br label %end
cmp.false:
%a3 = bitcast i16 %a to bfloat
br label %end
end:
%phi = phi bfloat [ %a2, %cmp.true ], [ %a3, %cmp.false ]
ret bfloat %phi
}
define i16 @bitcast_bf16_to_i16(bfloat %a, i32 %b) {
; GCN-LABEL: bitcast_bf16_to_i16:
; GCN: ; %bb.0:
; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GCN-NEXT: v_cmp_ne_u32_e32 vcc, 0, v1
; GCN-NEXT: v_mul_f32_e32 v1, 1.0, v0
; GCN-NEXT: ; implicit-def: $vgpr0
; GCN-NEXT: s_and_saveexec_b64 s[4:5], vcc
; GCN-NEXT: s_xor_b64 s[4:5], exec, s[4:5]
; GCN-NEXT: s_cbranch_execnz .LBB3_3
; GCN-NEXT: ; %bb.1: ; %Flow
; GCN-NEXT: s_andn2_saveexec_b64 s[4:5], s[4:5]
; GCN-NEXT: s_cbranch_execnz .LBB3_4
; GCN-NEXT: .LBB3_2: ; %end
; GCN-NEXT: s_or_b64 exec, exec, s[4:5]
; GCN-NEXT: s_setpc_b64 s[30:31]
; GCN-NEXT: .LBB3_3: ; %cmp.false
; GCN-NEXT: v_lshrrev_b32_e32 v0, 16, v1
; GCN-NEXT: ; implicit-def: $vgpr1
; GCN-NEXT: s_andn2_saveexec_b64 s[4:5], s[4:5]
; GCN-NEXT: s_cbranch_execz .LBB3_2
; GCN-NEXT: .LBB3_4: ; %cmp.true
; GCN-NEXT: v_and_b32_e32 v0, 0xffff0000, v1
; GCN-NEXT: v_add_f32_e32 v0, 0x40c00000, v0
; GCN-NEXT: v_lshrrev_b32_e32 v0, 16, v0
; GCN-NEXT: s_or_b64 exec, exec, s[4:5]
; GCN-NEXT: s_setpc_b64 s[30:31]
;
; VI-LABEL: bitcast_bf16_to_i16:
; VI: ; %bb.0:
; VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; VI-NEXT: v_cmp_ne_u32_e32 vcc, 0, v1
; VI-NEXT: s_and_saveexec_b64 s[4:5], vcc
; VI-NEXT: s_xor_b64 s[4:5], exec, s[4:5]
; VI-NEXT: s_andn2_saveexec_b64 s[4:5], s[4:5]
; VI-NEXT: ; %bb.1: ; %cmp.true
; VI-NEXT: v_lshlrev_b32_e32 v0, 16, v0
; VI-NEXT: v_add_f32_e32 v0, 0x40c00000, v0
; VI-NEXT: v_bfe_u32 v1, v0, 16, 1
; VI-NEXT: v_add_u32_e32 v1, vcc, v1, v0
; VI-NEXT: v_add_u32_e32 v1, vcc, 0x7fff, v1
; VI-NEXT: v_or_b32_e32 v2, 0x400000, v0
; VI-NEXT: v_cmp_u_f32_e32 vcc, v0, v0
; VI-NEXT: v_cndmask_b32_e32 v0, v1, v2, vcc
; VI-NEXT: v_lshrrev_b32_e32 v0, 16, v0
; VI-NEXT: ; %bb.2: ; %end
; VI-NEXT: s_or_b64 exec, exec, s[4:5]
; VI-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: bitcast_bf16_to_i16:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT: v_cmp_ne_u32_e32 vcc, 0, v1
; GFX9-NEXT: s_and_saveexec_b64 s[4:5], vcc
; GFX9-NEXT: s_xor_b64 s[4:5], exec, s[4:5]
; GFX9-NEXT: s_andn2_saveexec_b64 s[4:5], s[4:5]
; GFX9-NEXT: ; %bb.1: ; %cmp.true
; GFX9-NEXT: v_lshlrev_b32_e32 v0, 16, v0
; GFX9-NEXT: v_add_f32_e32 v0, 0x40c00000, v0
; GFX9-NEXT: v_bfe_u32 v1, v0, 16, 1
; GFX9-NEXT: s_movk_i32 s6, 0x7fff
; GFX9-NEXT: v_add3_u32 v1, v1, v0, s6
; GFX9-NEXT: v_or_b32_e32 v2, 0x400000, v0
; GFX9-NEXT: v_cmp_u_f32_e32 vcc, v0, v0
; GFX9-NEXT: v_cndmask_b32_e32 v0, v1, v2, vcc
; GFX9-NEXT: v_lshrrev_b32_e32 v0, 16, v0
; GFX9-NEXT: ; %bb.2: ; %end
; GFX9-NEXT: s_or_b64 exec, exec, s[4:5]
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-LABEL: bitcast_bf16_to_i16:
; GFX11: ; %bb.0:
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX11-NEXT: s_mov_b32 s0, exec_lo
; GFX11-NEXT: v_cmpx_ne_u32_e32 0, v1
; GFX11-NEXT: s_xor_b32 s0, exec_lo, s0
; GFX11-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
; GFX11-NEXT: s_and_not1_saveexec_b32 s0, s0
; GFX11-NEXT: s_cbranch_execz .LBB3_2
; GFX11-NEXT: ; %bb.1: ; %cmp.true
; GFX11-NEXT: v_lshlrev_b32_e32 v0, 16, v0
; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
; GFX11-NEXT: v_add_f32_e32 v0, 0x40c00000, v0
; GFX11-NEXT: v_bfe_u32 v1, v0, 16, 1
; GFX11-NEXT: v_or_b32_e32 v2, 0x400000, v0
; GFX11-NEXT: v_cmp_u_f32_e32 vcc_lo, v0, v0
; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_1)
; GFX11-NEXT: v_add3_u32 v1, v1, v0, 0x7fff
; GFX11-NEXT: v_cndmask_b32_e32 v0, v1, v2, vcc_lo
; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)
; GFX11-NEXT: v_lshrrev_b32_e32 v0, 16, v0
; GFX11-NEXT: .LBB3_2: ; %end
; GFX11-NEXT: s_or_b32 exec_lo, exec_lo, s0
; GFX11-NEXT: s_setpc_b64 s[30:31]
%cmp = icmp eq i32 %b, 0
br i1 %cmp, label %cmp.true, label %cmp.false
cmp.true:
%a1 = fadd bfloat %a, 0xR40C0
%a2 = bitcast bfloat %a1 to i16
br label %end
cmp.false:
%a3 = bitcast bfloat %a to i16
br label %end
end:
%phi = phi i16 [ %a2, %cmp.true ], [ %a3, %cmp.false ]
ret i16 %phi
}
define bfloat @bitcast_f16_to_bf16(half %a, i32 %b) {
; GCN-LABEL: bitcast_f16_to_bf16:
; GCN: ; %bb.0:
; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GCN-NEXT: v_cmp_ne_u32_e32 vcc, 0, v1
; GCN-NEXT: v_cvt_f16_f32_e32 v1, v0
; GCN-NEXT: ; implicit-def: $vgpr0
; GCN-NEXT: s_and_saveexec_b64 s[4:5], vcc
; GCN-NEXT: s_xor_b64 s[4:5], exec, s[4:5]
; GCN-NEXT: s_cbranch_execnz .LBB4_3
; GCN-NEXT: ; %bb.1: ; %Flow
; GCN-NEXT: s_andn2_saveexec_b64 s[4:5], s[4:5]
; GCN-NEXT: s_cbranch_execnz .LBB4_4
; GCN-NEXT: .LBB4_2: ; %end
; GCN-NEXT: s_or_b64 exec, exec, s[4:5]
; GCN-NEXT: s_setpc_b64 s[30:31]
; GCN-NEXT: .LBB4_3: ; %cmp.false
; GCN-NEXT: v_lshlrev_b32_e32 v0, 16, v1
; GCN-NEXT: ; implicit-def: $vgpr1
; GCN-NEXT: s_andn2_saveexec_b64 s[4:5], s[4:5]
; GCN-NEXT: s_cbranch_execz .LBB4_2
; GCN-NEXT: .LBB4_4: ; %cmp.true
; GCN-NEXT: v_cvt_f32_f16_e32 v0, v1
; GCN-NEXT: v_add_f32_e32 v0, 0x38000000, v0
; GCN-NEXT: v_cvt_f16_f32_e32 v0, v0
; GCN-NEXT: v_lshlrev_b32_e32 v0, 16, v0
; GCN-NEXT: s_or_b64 exec, exec, s[4:5]
; GCN-NEXT: s_setpc_b64 s[30:31]
;
; VI-LABEL: bitcast_f16_to_bf16:
; VI: ; %bb.0:
; VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; VI-NEXT: v_cmp_ne_u32_e32 vcc, 0, v1
; VI-NEXT: s_and_saveexec_b64 s[4:5], vcc
; VI-NEXT: s_xor_b64 s[4:5], exec, s[4:5]
; VI-NEXT: s_andn2_saveexec_b64 s[4:5], s[4:5]
; VI-NEXT: ; %bb.1: ; %cmp.true
; VI-NEXT: v_add_f16_e32 v0, 0x200, v0
; VI-NEXT: ; %bb.2: ; %end
; VI-NEXT: s_or_b64 exec, exec, s[4:5]
; VI-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: bitcast_f16_to_bf16:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT: v_cmp_ne_u32_e32 vcc, 0, v1
; GFX9-NEXT: s_and_saveexec_b64 s[4:5], vcc
; GFX9-NEXT: s_xor_b64 s[4:5], exec, s[4:5]
; GFX9-NEXT: s_andn2_saveexec_b64 s[4:5], s[4:5]
; GFX9-NEXT: ; %bb.1: ; %cmp.true
; GFX9-NEXT: v_add_f16_e32 v0, 0x200, v0
; GFX9-NEXT: ; %bb.2: ; %end
; GFX9-NEXT: s_or_b64 exec, exec, s[4:5]
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-LABEL: bitcast_f16_to_bf16:
; GFX11: ; %bb.0:
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX11-NEXT: s_mov_b32 s0, exec_lo
; GFX11-NEXT: v_cmpx_ne_u32_e32 0, v1
; GFX11-NEXT: s_xor_b32 s0, exec_lo, s0
; GFX11-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
; GFX11-NEXT: s_and_not1_saveexec_b32 s0, s0
; GFX11-NEXT: ; %bb.1: ; %cmp.true
; GFX11-NEXT: v_add_f16_e32 v0, 0x200, v0
; GFX11-NEXT: ; %bb.2: ; %end
; GFX11-NEXT: s_or_b32 exec_lo, exec_lo, s0
; GFX11-NEXT: s_setpc_b64 s[30:31]
%cmp = icmp eq i32 %b, 0
br i1 %cmp, label %cmp.true, label %cmp.false
cmp.true:
%a1 = fadd half %a, 0xH0200
%a2 = bitcast half %a1 to bfloat
br label %end
cmp.false:
%a3 = bitcast half %a to bfloat
br label %end
end:
%phi = phi bfloat [ %a2, %cmp.true ], [ %a3, %cmp.false ]
ret bfloat %phi
}
define half @bitcast_bf16_to_f16(bfloat %a, i32 %b) {
; GCN-LABEL: bitcast_bf16_to_f16:
; GCN: ; %bb.0:
; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GCN-NEXT: v_cmp_ne_u32_e32 vcc, 0, v1
; GCN-NEXT: v_mul_f32_e32 v1, 1.0, v0
; GCN-NEXT: ; implicit-def: $vgpr0
; GCN-NEXT: s_and_saveexec_b64 s[4:5], vcc
; GCN-NEXT: s_xor_b64 s[4:5], exec, s[4:5]
; GCN-NEXT: s_cbranch_execnz .LBB5_3
; GCN-NEXT: ; %bb.1: ; %Flow
; GCN-NEXT: s_andn2_saveexec_b64 s[4:5], s[4:5]
; GCN-NEXT: s_cbranch_execnz .LBB5_4
; GCN-NEXT: .LBB5_2: ; %end
; GCN-NEXT: s_or_b64 exec, exec, s[4:5]
; GCN-NEXT: s_setpc_b64 s[30:31]
; GCN-NEXT: .LBB5_3: ; %cmp.false
; GCN-NEXT: v_lshrrev_b32_e32 v0, 16, v1
; GCN-NEXT: v_cvt_f32_f16_e32 v0, v0
; GCN-NEXT: ; implicit-def: $vgpr1
; GCN-NEXT: s_andn2_saveexec_b64 s[4:5], s[4:5]
; GCN-NEXT: s_cbranch_execz .LBB5_2
; GCN-NEXT: .LBB5_4: ; %cmp.true
; GCN-NEXT: v_and_b32_e32 v0, 0xffff0000, v1
; GCN-NEXT: v_add_f32_e32 v0, 0x40c00000, v0
; GCN-NEXT: v_lshrrev_b32_e32 v0, 16, v0
; GCN-NEXT: v_cvt_f32_f16_e32 v0, v0
; GCN-NEXT: s_or_b64 exec, exec, s[4:5]
; GCN-NEXT: s_setpc_b64 s[30:31]
;
; VI-LABEL: bitcast_bf16_to_f16:
; VI: ; %bb.0:
; VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; VI-NEXT: v_cmp_ne_u32_e32 vcc, 0, v1
; VI-NEXT: s_and_saveexec_b64 s[4:5], vcc
; VI-NEXT: s_xor_b64 s[4:5], exec, s[4:5]
; VI-NEXT: s_andn2_saveexec_b64 s[4:5], s[4:5]
; VI-NEXT: ; %bb.1: ; %cmp.true
; VI-NEXT: v_lshlrev_b32_e32 v0, 16, v0
; VI-NEXT: v_add_f32_e32 v0, 0x40c00000, v0
; VI-NEXT: v_bfe_u32 v1, v0, 16, 1
; VI-NEXT: v_add_u32_e32 v1, vcc, v1, v0
; VI-NEXT: v_add_u32_e32 v1, vcc, 0x7fff, v1
; VI-NEXT: v_or_b32_e32 v2, 0x400000, v0
; VI-NEXT: v_cmp_u_f32_e32 vcc, v0, v0
; VI-NEXT: v_cndmask_b32_e32 v0, v1, v2, vcc
; VI-NEXT: v_lshrrev_b32_e32 v0, 16, v0
; VI-NEXT: ; %bb.2: ; %end
; VI-NEXT: s_or_b64 exec, exec, s[4:5]
; VI-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-LABEL: bitcast_bf16_to_f16:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT: v_cmp_ne_u32_e32 vcc, 0, v1
; GFX9-NEXT: s_and_saveexec_b64 s[4:5], vcc
; GFX9-NEXT: s_xor_b64 s[4:5], exec, s[4:5]
; GFX9-NEXT: s_andn2_saveexec_b64 s[4:5], s[4:5]
; GFX9-NEXT: ; %bb.1: ; %cmp.true
; GFX9-NEXT: v_lshlrev_b32_e32 v0, 16, v0
; GFX9-NEXT: v_add_f32_e32 v0, 0x40c00000, v0
; GFX9-NEXT: v_bfe_u32 v1, v0, 16, 1
; GFX9-NEXT: s_movk_i32 s6, 0x7fff
; GFX9-NEXT: v_add3_u32 v1, v1, v0, s6
; GFX9-NEXT: v_or_b32_e32 v2, 0x400000, v0
; GFX9-NEXT: v_cmp_u_f32_e32 vcc, v0, v0
; GFX9-NEXT: v_cndmask_b32_e32 v0, v1, v2, vcc
; GFX9-NEXT: v_lshrrev_b32_e32 v0, 16, v0
; GFX9-NEXT: ; %bb.2: ; %end
; GFX9-NEXT: s_or_b64 exec, exec, s[4:5]
; GFX9-NEXT: s_setpc_b64 s[30:31]
;
; GFX11-LABEL: bitcast_bf16_to_f16:
; GFX11: ; %bb.0:
; GFX11-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX11-NEXT: s_mov_b32 s0, exec_lo
; GFX11-NEXT: v_cmpx_ne_u32_e32 0, v1
; GFX11-NEXT: s_xor_b32 s0, exec_lo, s0
; GFX11-NEXT: s_delay_alu instid0(SALU_CYCLE_1)
; GFX11-NEXT: s_and_not1_saveexec_b32 s0, s0
; GFX11-NEXT: s_cbranch_execz .LBB5_2
; GFX11-NEXT: ; %bb.1: ; %cmp.true
; GFX11-NEXT: v_lshlrev_b32_e32 v0, 16, v0
; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
; GFX11-NEXT: v_add_f32_e32 v0, 0x40c00000, v0
; GFX11-NEXT: v_bfe_u32 v1, v0, 16, 1
; GFX11-NEXT: v_or_b32_e32 v2, 0x400000, v0
; GFX11-NEXT: v_cmp_u_f32_e32 vcc_lo, v0, v0
; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(NEXT) | instid1(VALU_DEP_1)
; GFX11-NEXT: v_add3_u32 v1, v1, v0, 0x7fff
; GFX11-NEXT: v_cndmask_b32_e32 v0, v1, v2, vcc_lo
; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1)
; GFX11-NEXT: v_lshrrev_b32_e32 v0, 16, v0
; GFX11-NEXT: .LBB5_2: ; %end
; GFX11-NEXT: s_or_b32 exec_lo, exec_lo, s0
; GFX11-NEXT: s_setpc_b64 s[30:31]
%cmp = icmp eq i32 %b, 0
br i1 %cmp, label %cmp.true, label %cmp.false
cmp.true:
%a1 = fadd bfloat %a, 0xR40C0
%a2 = bitcast bfloat %a1 to half
br label %end
cmp.false:
%a3 = bitcast bfloat %a to half
br label %end
end:
%phi = phi half [ %a2, %cmp.true ], [ %a3, %cmp.false ]
ret half %phi
}