blob: fc4f6507f273f4318f22504963c600c0da9e2c18 [file] [log] [blame] [edit]
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc -global-isel=0 -mtriple=amdgcn -mcpu=gfx900 < %s | FileCheck -check-prefixes=GFX9,GFX9-SDAG %s
; RUN: llc -global-isel=1 -mtriple=amdgcn -mcpu=gfx900 < %s | FileCheck -check-prefixes=GFX9,GFX9-GISEL %s
declare { half, half } @llvm.modf.f16(half)
declare { <2 x half>, <2 x half> } @llvm.modf.v2f16(<2 x half>)
declare { float, float } @llvm.modf.f32(float)
declare { <2 x float>, <2 x float> } @llvm.modf.v2f32(<2 x float>)
declare { double, double } @llvm.modf.f64(double)
declare { <2 x double>, <2 x double> } @llvm.modf.v2f64(<2 x double>)
define { half, half } @test_modf_f16(half %x) {
; GFX9-SDAG-LABEL: test_modf_f16:
; GFX9-SDAG: ; %bb.0:
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-SDAG-NEXT: s_movk_i32 s4, 0x7c00
; GFX9-SDAG-NEXT: v_trunc_f16_e32 v1, v0
; GFX9-SDAG-NEXT: v_sub_f16_e32 v2, v0, v1
; GFX9-SDAG-NEXT: v_cmp_neq_f16_e64 vcc, |v0|, s4
; GFX9-SDAG-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
; GFX9-SDAG-NEXT: s_movk_i32 s4, 0x7fff
; GFX9-SDAG-NEXT: v_bfi_b32 v0, s4, v2, v0
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-GISEL-LABEL: test_modf_f16:
; GFX9-GISEL: ; %bb.0:
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-GISEL-NEXT: v_trunc_f16_e32 v1, v0
; GFX9-GISEL-NEXT: v_mov_b32_e32 v3, 0x7c00
; GFX9-GISEL-NEXT: v_sub_f16_e32 v2, v0, v1
; GFX9-GISEL-NEXT: v_cmp_eq_f16_e64 s[4:5], |v0|, v3
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v2, v2, 0, s[4:5]
; GFX9-GISEL-NEXT: v_and_b32_e32 v2, 0x7fff, v2
; GFX9-GISEL-NEXT: v_and_b32_e32 v0, 0xffff8000, v0
; GFX9-GISEL-NEXT: v_or_b32_e32 v0, v2, v0
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
%result = call { half, half } @llvm.modf.f16(half %x)
ret { half, half } %result
}
define half @test_modf_f16_only_use_fract(half %x) {
; GFX9-SDAG-LABEL: test_modf_f16_only_use_fract:
; GFX9-SDAG: ; %bb.0:
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-SDAG-NEXT: s_movk_i32 s4, 0x7c00
; GFX9-SDAG-NEXT: v_trunc_f16_e32 v1, v0
; GFX9-SDAG-NEXT: v_sub_f16_e32 v1, v0, v1
; GFX9-SDAG-NEXT: v_cmp_neq_f16_e64 vcc, |v0|, s4
; GFX9-SDAG-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
; GFX9-SDAG-NEXT: s_movk_i32 s4, 0x7fff
; GFX9-SDAG-NEXT: v_bfi_b32 v0, s4, v1, v0
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-GISEL-LABEL: test_modf_f16_only_use_fract:
; GFX9-GISEL: ; %bb.0:
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-GISEL-NEXT: v_trunc_f16_e32 v1, v0
; GFX9-GISEL-NEXT: v_mov_b32_e32 v2, 0x7c00
; GFX9-GISEL-NEXT: v_sub_f16_e32 v1, v0, v1
; GFX9-GISEL-NEXT: v_cmp_eq_f16_e64 s[4:5], |v0|, v2
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v1, v1, 0, s[4:5]
; GFX9-GISEL-NEXT: v_and_b32_e32 v1, 0x7fff, v1
; GFX9-GISEL-NEXT: v_and_b32_e32 v0, 0xffff8000, v0
; GFX9-GISEL-NEXT: v_or_b32_e32 v0, v1, v0
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
%result = call { half, half } @llvm.modf.f16(half %x)
%result.0 = extractvalue { half, half } %result, 0
ret half %result.0
}
define half @test_modf_f16_only_use_integer(half %x) {
; GFX9-LABEL: test_modf_f16_only_use_integer:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT: v_trunc_f16_e32 v0, v0
; GFX9-NEXT: s_setpc_b64 s[30:31]
%result = call { half, half } @llvm.modf.f16(half %x)
%result.1 = extractvalue { half, half } %result, 1
ret half %result.1
}
define { <2 x half>, <2 x half> } @test_modf_v2f16(<2 x half> %x) {
; GFX9-SDAG-LABEL: test_modf_v2f16:
; GFX9-SDAG: ; %bb.0:
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-SDAG-NEXT: s_movk_i32 s4, 0x7c00
; GFX9-SDAG-NEXT: v_trunc_f16_e32 v1, v0
; GFX9-SDAG-NEXT: v_sub_f16_e32 v2, v0, v1
; GFX9-SDAG-NEXT: v_cmp_neq_f16_e64 vcc, |v0|, s4
; GFX9-SDAG-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
; GFX9-SDAG-NEXT: s_movk_i32 s5, 0x7fff
; GFX9-SDAG-NEXT: v_bfi_b32 v2, s5, v2, v0
; GFX9-SDAG-NEXT: v_lshrrev_b32_e32 v0, 16, v0
; GFX9-SDAG-NEXT: v_trunc_f16_e32 v3, v0
; GFX9-SDAG-NEXT: v_sub_f16_e32 v4, v0, v3
; GFX9-SDAG-NEXT: v_cmp_neq_f16_e64 vcc, |v0|, s4
; GFX9-SDAG-NEXT: v_cndmask_b32_e32 v4, 0, v4, vcc
; GFX9-SDAG-NEXT: v_bfi_b32 v0, s5, v4, v0
; GFX9-SDAG-NEXT: v_pack_b32_f16 v0, v2, v0
; GFX9-SDAG-NEXT: v_pack_b32_f16 v1, v1, v3
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-GISEL-LABEL: test_modf_v2f16:
; GFX9-GISEL: ; %bb.0:
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-GISEL-NEXT: v_trunc_f16_e32 v1, v0
; GFX9-GISEL-NEXT: v_mov_b32_e32 v3, 0x7c00
; GFX9-GISEL-NEXT: v_sub_f16_e32 v2, v0, v1
; GFX9-GISEL-NEXT: v_cmp_eq_f16_e64 s[4:5], |v0|, v3
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v2, v2, 0, s[4:5]
; GFX9-GISEL-NEXT: v_and_b32_e32 v2, 0x7fff, v2
; GFX9-GISEL-NEXT: v_and_b32_e32 v5, 0xffff8000, v0
; GFX9-GISEL-NEXT: v_or_b32_e32 v2, v2, v5
; GFX9-GISEL-NEXT: v_trunc_f16_sdwa v5, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
; GFX9-GISEL-NEXT: v_sub_f16_sdwa v6, v0, v5 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:DWORD
; GFX9-GISEL-NEXT: v_cmp_eq_f16_sdwa s[4:5], |v0|, v3 src0_sel:WORD_1 src1_sel:DWORD
; GFX9-GISEL-NEXT: v_mov_b32_e32 v4, 0xffff8000
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v3, v6, 0, s[4:5]
; GFX9-GISEL-NEXT: v_and_b32_e32 v3, 0x7fff, v3
; GFX9-GISEL-NEXT: v_and_b32_sdwa v0, v0, v4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:DWORD
; GFX9-GISEL-NEXT: v_or_b32_e32 v0, v3, v0
; GFX9-GISEL-NEXT: v_and_b32_e32 v2, 0xffff, v2
; GFX9-GISEL-NEXT: v_lshl_or_b32 v0, v0, 16, v2
; GFX9-GISEL-NEXT: v_pack_b32_f16 v1, v1, v5
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
%result = call { <2 x half>, <2 x half> } @llvm.modf.v2f16(<2 x half> %x)
ret { <2 x half>, <2 x half> } %result
}
define <2 x half> @test_modf_v2f16_only_use_fract(<2 x half> %x) {
; GFX9-SDAG-LABEL: test_modf_v2f16_only_use_fract:
; GFX9-SDAG: ; %bb.0:
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-SDAG-NEXT: s_movk_i32 s4, 0x7c00
; GFX9-SDAG-NEXT: v_trunc_f16_e32 v1, v0
; GFX9-SDAG-NEXT: v_sub_f16_e32 v1, v0, v1
; GFX9-SDAG-NEXT: v_cmp_neq_f16_e64 vcc, |v0|, s4
; GFX9-SDAG-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
; GFX9-SDAG-NEXT: s_movk_i32 s5, 0x7fff
; GFX9-SDAG-NEXT: v_bfi_b32 v1, s5, v1, v0
; GFX9-SDAG-NEXT: v_lshrrev_b32_e32 v0, 16, v0
; GFX9-SDAG-NEXT: v_trunc_f16_e32 v2, v0
; GFX9-SDAG-NEXT: v_sub_f16_e32 v2, v0, v2
; GFX9-SDAG-NEXT: v_cmp_neq_f16_e64 vcc, |v0|, s4
; GFX9-SDAG-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
; GFX9-SDAG-NEXT: v_bfi_b32 v0, s5, v2, v0
; GFX9-SDAG-NEXT: v_pack_b32_f16 v0, v1, v0
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-GISEL-LABEL: test_modf_v2f16_only_use_fract:
; GFX9-GISEL: ; %bb.0:
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-GISEL-NEXT: v_trunc_f16_e32 v1, v0
; GFX9-GISEL-NEXT: v_mov_b32_e32 v2, 0x7c00
; GFX9-GISEL-NEXT: v_sub_f16_e32 v1, v0, v1
; GFX9-GISEL-NEXT: v_cmp_eq_f16_e64 s[4:5], |v0|, v2
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v1, v1, 0, s[4:5]
; GFX9-GISEL-NEXT: v_and_b32_e32 v1, 0x7fff, v1
; GFX9-GISEL-NEXT: v_and_b32_e32 v4, 0xffff8000, v0
; GFX9-GISEL-NEXT: v_or_b32_e32 v1, v1, v4
; GFX9-GISEL-NEXT: v_trunc_f16_sdwa v4, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
; GFX9-GISEL-NEXT: v_sub_f16_sdwa v4, v0, v4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:DWORD
; GFX9-GISEL-NEXT: v_cmp_eq_f16_sdwa s[4:5], |v0|, v2 src0_sel:WORD_1 src1_sel:DWORD
; GFX9-GISEL-NEXT: v_mov_b32_e32 v3, 0xffff8000
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v2, v4, 0, s[4:5]
; GFX9-GISEL-NEXT: v_and_b32_e32 v2, 0x7fff, v2
; GFX9-GISEL-NEXT: v_and_b32_sdwa v0, v0, v3 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:DWORD
; GFX9-GISEL-NEXT: v_or_b32_e32 v0, v2, v0
; GFX9-GISEL-NEXT: v_and_b32_e32 v1, 0xffff, v1
; GFX9-GISEL-NEXT: v_lshl_or_b32 v0, v0, 16, v1
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
%result = call { <2 x half>, <2 x half> } @llvm.modf.v2f16(<2 x half> %x)
%result.0 = extractvalue { <2 x half>, <2 x half> } %result, 0
ret <2 x half> %result.0
}
define <2 x half> @test_modf_v2f16_only_use_integer(<2 x half> %x) {
; GFX9-SDAG-LABEL: test_modf_v2f16_only_use_integer:
; GFX9-SDAG: ; %bb.0:
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-SDAG-NEXT: v_trunc_f16_sdwa v1, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
; GFX9-SDAG-NEXT: v_trunc_f16_e32 v0, v0
; GFX9-SDAG-NEXT: v_pack_b32_f16 v0, v0, v1
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-GISEL-LABEL: test_modf_v2f16_only_use_integer:
; GFX9-GISEL: ; %bb.0:
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-GISEL-NEXT: v_trunc_f16_e32 v1, v0
; GFX9-GISEL-NEXT: v_trunc_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
; GFX9-GISEL-NEXT: v_pack_b32_f16 v0, v1, v0
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
%result = call { <2 x half>, <2 x half> } @llvm.modf.v2f16(<2 x half> %x)
%result.1 = extractvalue { <2 x half>, <2 x half> } %result, 1
ret <2 x half> %result.1
}
define { float, float } @test_modf_f32(float %x) {
; GFX9-SDAG-LABEL: test_modf_f32:
; GFX9-SDAG: ; %bb.0:
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-SDAG-NEXT: s_mov_b32 s4, 0x7f800000
; GFX9-SDAG-NEXT: v_trunc_f32_e32 v1, v0
; GFX9-SDAG-NEXT: v_sub_f32_e32 v2, v0, v1
; GFX9-SDAG-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s4
; GFX9-SDAG-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
; GFX9-SDAG-NEXT: s_brev_b32 s4, -2
; GFX9-SDAG-NEXT: v_bfi_b32 v0, s4, v2, v0
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-GISEL-LABEL: test_modf_f32:
; GFX9-GISEL: ; %bb.0:
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-GISEL-NEXT: v_trunc_f32_e32 v1, v0
; GFX9-GISEL-NEXT: v_mov_b32_e32 v3, 0x7f800000
; GFX9-GISEL-NEXT: v_sub_f32_e32 v2, v0, v1
; GFX9-GISEL-NEXT: v_cmp_eq_f32_e64 s[4:5], |v0|, v3
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v2, v2, 0, s[4:5]
; GFX9-GISEL-NEXT: v_bfrev_b32_e32 v3, -2
; GFX9-GISEL-NEXT: v_and_b32_e32 v0, 0x80000000, v0
; GFX9-GISEL-NEXT: v_and_or_b32 v0, v2, v3, v0
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
%result = call { float, float } @llvm.modf.f32(float %x)
ret { float, float } %result
}
define float @test_modf_f32_only_use_fract(float %x) {
; GFX9-SDAG-LABEL: test_modf_f32_only_use_fract:
; GFX9-SDAG: ; %bb.0:
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-SDAG-NEXT: s_mov_b32 s4, 0x7f800000
; GFX9-SDAG-NEXT: v_trunc_f32_e32 v1, v0
; GFX9-SDAG-NEXT: v_sub_f32_e32 v1, v0, v1
; GFX9-SDAG-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s4
; GFX9-SDAG-NEXT: v_cndmask_b32_e32 v1, 0, v1, vcc
; GFX9-SDAG-NEXT: s_brev_b32 s4, -2
; GFX9-SDAG-NEXT: v_bfi_b32 v0, s4, v1, v0
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-GISEL-LABEL: test_modf_f32_only_use_fract:
; GFX9-GISEL: ; %bb.0:
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-GISEL-NEXT: v_trunc_f32_e32 v1, v0
; GFX9-GISEL-NEXT: v_mov_b32_e32 v2, 0x7f800000
; GFX9-GISEL-NEXT: v_sub_f32_e32 v1, v0, v1
; GFX9-GISEL-NEXT: v_cmp_eq_f32_e64 s[4:5], |v0|, v2
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v1, v1, 0, s[4:5]
; GFX9-GISEL-NEXT: v_bfrev_b32_e32 v2, -2
; GFX9-GISEL-NEXT: v_and_b32_e32 v0, 0x80000000, v0
; GFX9-GISEL-NEXT: v_and_or_b32 v0, v1, v2, v0
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
%result = call { float, float } @llvm.modf.f32(float %x)
%result.0 = extractvalue { float, float } %result, 0
ret float %result.0
}
define float @test_modf_f32_only_use_integer(float %x) {
; GFX9-LABEL: test_modf_f32_only_use_integer:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT: v_trunc_f32_e32 v0, v0
; GFX9-NEXT: s_setpc_b64 s[30:31]
%result = call { float, float } @llvm.modf.f32(float %x)
%result.1 = extractvalue { float, float } %result, 1
ret float %result.1
}
define { <2 x float>, <2 x float> } @test_modf_v2f32(<2 x float> %x) {
; GFX9-SDAG-LABEL: test_modf_v2f32:
; GFX9-SDAG: ; %bb.0:
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-SDAG-NEXT: s_mov_b32 s4, 0x7f800000
; GFX9-SDAG-NEXT: v_trunc_f32_e32 v2, v0
; GFX9-SDAG-NEXT: v_sub_f32_e32 v3, v0, v2
; GFX9-SDAG-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s4
; GFX9-SDAG-NEXT: v_cndmask_b32_e32 v3, 0, v3, vcc
; GFX9-SDAG-NEXT: s_brev_b32 s5, -2
; GFX9-SDAG-NEXT: v_bfi_b32 v0, s5, v3, v0
; GFX9-SDAG-NEXT: v_trunc_f32_e32 v3, v1
; GFX9-SDAG-NEXT: v_sub_f32_e32 v4, v1, v3
; GFX9-SDAG-NEXT: v_cmp_neq_f32_e64 vcc, |v1|, s4
; GFX9-SDAG-NEXT: v_cndmask_b32_e32 v4, 0, v4, vcc
; GFX9-SDAG-NEXT: v_bfi_b32 v1, s5, v4, v1
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-GISEL-LABEL: test_modf_v2f32:
; GFX9-GISEL: ; %bb.0:
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-GISEL-NEXT: v_trunc_f32_e32 v2, v0
; GFX9-GISEL-NEXT: v_mov_b32_e32 v4, 0x7f800000
; GFX9-GISEL-NEXT: v_sub_f32_e32 v3, v0, v2
; GFX9-GISEL-NEXT: v_cmp_eq_f32_e64 s[4:5], |v0|, v4
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v3, v3, 0, s[4:5]
; GFX9-GISEL-NEXT: v_bfrev_b32_e32 v5, -2
; GFX9-GISEL-NEXT: v_and_b32_e32 v0, 0x80000000, v0
; GFX9-GISEL-NEXT: v_and_or_b32 v0, v3, v5, v0
; GFX9-GISEL-NEXT: v_trunc_f32_e32 v3, v1
; GFX9-GISEL-NEXT: v_sub_f32_e32 v6, v1, v3
; GFX9-GISEL-NEXT: v_cmp_eq_f32_e64 s[4:5], |v1|, v4
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v4, v6, 0, s[4:5]
; GFX9-GISEL-NEXT: v_and_b32_e32 v1, 0x80000000, v1
; GFX9-GISEL-NEXT: v_and_or_b32 v1, v4, v5, v1
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
%result = call { <2 x float>, <2 x float> } @llvm.modf.v2f32(<2 x float> %x)
ret { <2 x float>, <2 x float> } %result
}
define <2 x float> @test_modf_v2f32_only_use_fract(<2 x float> %x) {
; GFX9-SDAG-LABEL: test_modf_v2f32_only_use_fract:
; GFX9-SDAG: ; %bb.0:
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-SDAG-NEXT: s_mov_b32 s4, 0x7f800000
; GFX9-SDAG-NEXT: v_trunc_f32_e32 v2, v0
; GFX9-SDAG-NEXT: v_sub_f32_e32 v2, v0, v2
; GFX9-SDAG-NEXT: v_cmp_neq_f32_e64 vcc, |v0|, s4
; GFX9-SDAG-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
; GFX9-SDAG-NEXT: s_brev_b32 s5, -2
; GFX9-SDAG-NEXT: v_bfi_b32 v0, s5, v2, v0
; GFX9-SDAG-NEXT: v_trunc_f32_e32 v2, v1
; GFX9-SDAG-NEXT: v_sub_f32_e32 v2, v1, v2
; GFX9-SDAG-NEXT: v_cmp_neq_f32_e64 vcc, |v1|, s4
; GFX9-SDAG-NEXT: v_cndmask_b32_e32 v2, 0, v2, vcc
; GFX9-SDAG-NEXT: v_bfi_b32 v1, s5, v2, v1
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-GISEL-LABEL: test_modf_v2f32_only_use_fract:
; GFX9-GISEL: ; %bb.0:
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-GISEL-NEXT: v_trunc_f32_e32 v2, v0
; GFX9-GISEL-NEXT: v_mov_b32_e32 v3, 0x7f800000
; GFX9-GISEL-NEXT: v_sub_f32_e32 v2, v0, v2
; GFX9-GISEL-NEXT: v_cmp_eq_f32_e64 s[4:5], |v0|, v3
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v2, v2, 0, s[4:5]
; GFX9-GISEL-NEXT: v_bfrev_b32_e32 v4, -2
; GFX9-GISEL-NEXT: v_and_b32_e32 v0, 0x80000000, v0
; GFX9-GISEL-NEXT: v_and_or_b32 v0, v2, v4, v0
; GFX9-GISEL-NEXT: v_trunc_f32_e32 v2, v1
; GFX9-GISEL-NEXT: v_sub_f32_e32 v2, v1, v2
; GFX9-GISEL-NEXT: v_cmp_eq_f32_e64 s[4:5], |v1|, v3
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v2, v2, 0, s[4:5]
; GFX9-GISEL-NEXT: v_and_b32_e32 v1, 0x80000000, v1
; GFX9-GISEL-NEXT: v_and_or_b32 v1, v2, v4, v1
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
%result = call { <2 x float>, <2 x float> } @llvm.modf.v2f32(<2 x float> %x)
%result.0 = extractvalue { <2 x float>, <2 x float> } %result, 0
ret <2 x float> %result.0
}
define <2 x float> @test_modf_v2f32_only_use_integer(<2 x float> %x) {
; GFX9-LABEL: test_modf_v2f32_only_use_integer:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT: v_trunc_f32_e32 v0, v0
; GFX9-NEXT: v_trunc_f32_e32 v1, v1
; GFX9-NEXT: s_setpc_b64 s[30:31]
%result = call { <2 x float>, <2 x float> } @llvm.modf.v2f32(<2 x float> %x)
%result.1 = extractvalue { <2 x float>, <2 x float> } %result, 1
ret <2 x float> %result.1
}
define { double, double } @test_modf_f64(double %x) {
; GFX9-SDAG-LABEL: test_modf_f64:
; GFX9-SDAG: ; %bb.0:
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-SDAG-NEXT: v_trunc_f64_e32 v[2:3], v[0:1]
; GFX9-SDAG-NEXT: s_movk_i32 s4, 0x204
; GFX9-SDAG-NEXT: v_cmp_class_f64_e64 s[4:5], v[0:1], s4
; GFX9-SDAG-NEXT: s_brev_b32 s6, -2
; GFX9-SDAG-NEXT: v_add_f64 v[4:5], v[0:1], -v[2:3]
; GFX9-SDAG-NEXT: v_cndmask_b32_e64 v0, v4, 0, s[4:5]
; GFX9-SDAG-NEXT: v_cndmask_b32_e64 v4, v5, 0, s[4:5]
; GFX9-SDAG-NEXT: v_bfi_b32 v1, s6, v4, v1
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-GISEL-LABEL: test_modf_f64:
; GFX9-GISEL: ; %bb.0:
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-GISEL-NEXT: v_trunc_f64_e32 v[2:3], v[0:1]
; GFX9-GISEL-NEXT: v_mov_b32_e32 v4, 0
; GFX9-GISEL-NEXT: v_mov_b32_e32 v5, 0x7ff00000
; GFX9-GISEL-NEXT: v_cmp_eq_f64_e64 s[4:5], |v[0:1]|, v[4:5]
; GFX9-GISEL-NEXT: v_bfrev_b32_e32 v4, -2
; GFX9-GISEL-NEXT: v_add_f64 v[6:7], v[0:1], -v[2:3]
; GFX9-GISEL-NEXT: v_and_b32_e32 v1, 0x80000000, v1
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v5, v6, 0, s[4:5]
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v6, v7, 0, s[4:5]
; GFX9-GISEL-NEXT: v_and_or_b32 v0, v0, 0, v5
; GFX9-GISEL-NEXT: v_and_or_b32 v1, v6, v4, v1
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
%result = call { double, double } @llvm.modf.f64(double %x)
ret { double, double } %result
}
define double @test_modf_f64_only_use_fract(double %x) {
; GFX9-SDAG-LABEL: test_modf_f64_only_use_fract:
; GFX9-SDAG: ; %bb.0:
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-SDAG-NEXT: v_trunc_f64_e32 v[2:3], v[0:1]
; GFX9-SDAG-NEXT: s_movk_i32 s4, 0x204
; GFX9-SDAG-NEXT: v_cmp_class_f64_e64 s[4:5], v[0:1], s4
; GFX9-SDAG-NEXT: s_brev_b32 s6, -2
; GFX9-SDAG-NEXT: v_add_f64 v[2:3], v[0:1], -v[2:3]
; GFX9-SDAG-NEXT: v_cndmask_b32_e64 v0, v2, 0, s[4:5]
; GFX9-SDAG-NEXT: v_cndmask_b32_e64 v2, v3, 0, s[4:5]
; GFX9-SDAG-NEXT: v_bfi_b32 v1, s6, v2, v1
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-GISEL-LABEL: test_modf_f64_only_use_fract:
; GFX9-GISEL: ; %bb.0:
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-GISEL-NEXT: v_trunc_f64_e32 v[2:3], v[0:1]
; GFX9-GISEL-NEXT: v_mov_b32_e32 v4, 0
; GFX9-GISEL-NEXT: v_mov_b32_e32 v5, 0x7ff00000
; GFX9-GISEL-NEXT: v_cmp_eq_f64_e64 s[4:5], |v[0:1]|, v[4:5]
; GFX9-GISEL-NEXT: v_bfrev_b32_e32 v4, -2
; GFX9-GISEL-NEXT: v_add_f64 v[2:3], v[0:1], -v[2:3]
; GFX9-GISEL-NEXT: v_and_b32_e32 v1, 0x80000000, v1
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v2, v2, 0, s[4:5]
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v3, v3, 0, s[4:5]
; GFX9-GISEL-NEXT: v_and_or_b32 v0, v0, 0, v2
; GFX9-GISEL-NEXT: v_and_or_b32 v1, v3, v4, v1
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
%result = call { double, double } @llvm.modf.f64(double %x)
%result.0 = extractvalue { double, double } %result, 0
ret double %result.0
}
define double @test_modf_f64_only_use_integer(double %x) {
; GFX9-LABEL: test_modf_f64_only_use_integer:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT: v_trunc_f64_e32 v[0:1], v[0:1]
; GFX9-NEXT: s_setpc_b64 s[30:31]
%result = call { double, double } @llvm.modf.f64(double %x)
%result.1 = extractvalue { double, double } %result, 1
ret double %result.1
}
define { <2 x double>, <2 x double> } @test_modf_v2f64(<2 x double> %x) {
; GFX9-SDAG-LABEL: test_modf_v2f64:
; GFX9-SDAG: ; %bb.0:
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-SDAG-NEXT: v_trunc_f64_e32 v[4:5], v[0:1]
; GFX9-SDAG-NEXT: v_trunc_f64_e32 v[6:7], v[2:3]
; GFX9-SDAG-NEXT: s_movk_i32 s6, 0x204
; GFX9-SDAG-NEXT: v_cmp_class_f64_e64 s[4:5], v[0:1], s6
; GFX9-SDAG-NEXT: v_cmp_class_f64_e64 s[6:7], v[2:3], s6
; GFX9-SDAG-NEXT: s_brev_b32 s8, -2
; GFX9-SDAG-NEXT: v_add_f64 v[8:9], v[0:1], -v[4:5]
; GFX9-SDAG-NEXT: v_add_f64 v[10:11], v[2:3], -v[6:7]
; GFX9-SDAG-NEXT: v_cndmask_b32_e64 v0, v8, 0, s[4:5]
; GFX9-SDAG-NEXT: v_cndmask_b32_e64 v8, v9, 0, s[4:5]
; GFX9-SDAG-NEXT: v_cndmask_b32_e64 v9, v11, 0, s[6:7]
; GFX9-SDAG-NEXT: v_cndmask_b32_e64 v2, v10, 0, s[6:7]
; GFX9-SDAG-NEXT: v_bfi_b32 v1, s8, v8, v1
; GFX9-SDAG-NEXT: v_bfi_b32 v3, s8, v9, v3
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-GISEL-LABEL: test_modf_v2f64:
; GFX9-GISEL: ; %bb.0:
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-GISEL-NEXT: v_trunc_f64_e32 v[4:5], v[0:1]
; GFX9-GISEL-NEXT: v_trunc_f64_e32 v[6:7], v[2:3]
; GFX9-GISEL-NEXT: v_mov_b32_e32 v8, 0
; GFX9-GISEL-NEXT: v_mov_b32_e32 v9, 0x7ff00000
; GFX9-GISEL-NEXT: v_cmp_eq_f64_e64 s[4:5], |v[0:1]|, v[8:9]
; GFX9-GISEL-NEXT: v_cmp_eq_f64_e64 s[6:7], |v[2:3]|, v[8:9]
; GFX9-GISEL-NEXT: v_bfrev_b32_e32 v8, -2
; GFX9-GISEL-NEXT: v_add_f64 v[10:11], v[0:1], -v[4:5]
; GFX9-GISEL-NEXT: v_add_f64 v[12:13], v[2:3], -v[6:7]
; GFX9-GISEL-NEXT: v_and_b32_e32 v1, 0x80000000, v1
; GFX9-GISEL-NEXT: v_and_b32_e32 v3, 0x80000000, v3
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v9, v10, 0, s[4:5]
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v10, v11, 0, s[4:5]
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v11, v12, 0, s[6:7]
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v12, v13, 0, s[6:7]
; GFX9-GISEL-NEXT: v_and_or_b32 v0, v0, 0, v9
; GFX9-GISEL-NEXT: v_and_or_b32 v1, v10, v8, v1
; GFX9-GISEL-NEXT: v_and_or_b32 v2, v2, 0, v11
; GFX9-GISEL-NEXT: v_and_or_b32 v3, v12, v8, v3
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
%result = call { <2 x double>, <2 x double> } @llvm.modf.v2f64(<2 x double> %x)
ret { <2 x double>, <2 x double> } %result
}
define <2 x double> @test_modf_v2f64_only_use_fract(<2 x double> %x) {
; GFX9-SDAG-LABEL: test_modf_v2f64_only_use_fract:
; GFX9-SDAG: ; %bb.0:
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-SDAG-NEXT: v_trunc_f64_e32 v[4:5], v[0:1]
; GFX9-SDAG-NEXT: v_trunc_f64_e32 v[6:7], v[2:3]
; GFX9-SDAG-NEXT: s_movk_i32 s6, 0x204
; GFX9-SDAG-NEXT: v_cmp_class_f64_e64 s[4:5], v[0:1], s6
; GFX9-SDAG-NEXT: v_cmp_class_f64_e64 s[6:7], v[2:3], s6
; GFX9-SDAG-NEXT: s_brev_b32 s8, -2
; GFX9-SDAG-NEXT: v_add_f64 v[4:5], v[0:1], -v[4:5]
; GFX9-SDAG-NEXT: v_add_f64 v[6:7], v[2:3], -v[6:7]
; GFX9-SDAG-NEXT: v_cndmask_b32_e64 v0, v4, 0, s[4:5]
; GFX9-SDAG-NEXT: v_cndmask_b32_e64 v4, v5, 0, s[4:5]
; GFX9-SDAG-NEXT: v_cndmask_b32_e64 v5, v7, 0, s[6:7]
; GFX9-SDAG-NEXT: v_cndmask_b32_e64 v2, v6, 0, s[6:7]
; GFX9-SDAG-NEXT: v_bfi_b32 v1, s8, v4, v1
; GFX9-SDAG-NEXT: v_bfi_b32 v3, s8, v5, v3
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-GISEL-LABEL: test_modf_v2f64_only_use_fract:
; GFX9-GISEL: ; %bb.0:
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-GISEL-NEXT: v_trunc_f64_e32 v[4:5], v[0:1]
; GFX9-GISEL-NEXT: v_trunc_f64_e32 v[6:7], v[2:3]
; GFX9-GISEL-NEXT: v_mov_b32_e32 v8, 0
; GFX9-GISEL-NEXT: v_mov_b32_e32 v9, 0x7ff00000
; GFX9-GISEL-NEXT: v_cmp_eq_f64_e64 s[4:5], |v[0:1]|, v[8:9]
; GFX9-GISEL-NEXT: v_cmp_eq_f64_e64 s[6:7], |v[2:3]|, v[8:9]
; GFX9-GISEL-NEXT: v_bfrev_b32_e32 v8, -2
; GFX9-GISEL-NEXT: v_add_f64 v[4:5], v[0:1], -v[4:5]
; GFX9-GISEL-NEXT: v_add_f64 v[6:7], v[2:3], -v[6:7]
; GFX9-GISEL-NEXT: v_and_b32_e32 v1, 0x80000000, v1
; GFX9-GISEL-NEXT: v_and_b32_e32 v3, 0x80000000, v3
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v4, v4, 0, s[4:5]
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v5, v5, 0, s[4:5]
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v6, v6, 0, s[6:7]
; GFX9-GISEL-NEXT: v_cndmask_b32_e64 v7, v7, 0, s[6:7]
; GFX9-GISEL-NEXT: v_and_or_b32 v0, v0, 0, v4
; GFX9-GISEL-NEXT: v_and_or_b32 v1, v5, v8, v1
; GFX9-GISEL-NEXT: v_and_or_b32 v2, v2, 0, v6
; GFX9-GISEL-NEXT: v_and_or_b32 v3, v7, v8, v3
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
%result = call { <2 x double>, <2 x double> } @llvm.modf.v2f64(<2 x double> %x)
%result.0 = extractvalue { <2 x double>, <2 x double> } %result, 0
ret <2 x double> %result.0
}
define <2 x double> @test_modf_v2f64_only_use_integer(<2 x double> %x) {
; GFX9-LABEL: test_modf_v2f64_only_use_integer:
; GFX9: ; %bb.0:
; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-NEXT: v_trunc_f64_e32 v[0:1], v[0:1]
; GFX9-NEXT: v_trunc_f64_e32 v[2:3], v[2:3]
; GFX9-NEXT: s_setpc_b64 s[30:31]
%result = call { <2 x double>, <2 x double> } @llvm.modf.v2f64(<2 x double> %x)
%result.1 = extractvalue { <2 x double>, <2 x double> } %result, 1
ret <2 x double> %result.1
}
define { float, float } @test_modf_ninf(float %x) {
; GFX9-SDAG-LABEL: test_modf_ninf:
; GFX9-SDAG: ; %bb.0:
; GFX9-SDAG-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-SDAG-NEXT: v_trunc_f32_e32 v1, v0
; GFX9-SDAG-NEXT: v_sub_f32_e32 v2, v0, v1
; GFX9-SDAG-NEXT: s_brev_b32 s4, -2
; GFX9-SDAG-NEXT: v_bfi_b32 v0, s4, v2, v0
; GFX9-SDAG-NEXT: s_setpc_b64 s[30:31]
;
; GFX9-GISEL-LABEL: test_modf_ninf:
; GFX9-GISEL: ; %bb.0:
; GFX9-GISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX9-GISEL-NEXT: v_trunc_f32_e32 v1, v0
; GFX9-GISEL-NEXT: v_sub_f32_e32 v2, v0, v1
; GFX9-GISEL-NEXT: v_bfrev_b32_e32 v3, -2
; GFX9-GISEL-NEXT: v_and_b32_e32 v0, 0x80000000, v0
; GFX9-GISEL-NEXT: v_and_or_b32 v0, v2, v3, v0
; GFX9-GISEL-NEXT: s_setpc_b64 s[30:31]
%result = call ninf { float, float } @llvm.modf.f32(float %x)
ret { float, float } %result
}