| ; 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 |
| } |