| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: llc -global-isel=0 -mtriple=amdgpu9.00-amd-amdhsa < %s | FileCheck -check-prefix=SDAG %s |
| ; RUN: llc -global-isel=1 -mtriple=amdgpu9.00-amd-amdhsa < %s | FileCheck -check-prefix=GISEL %s |
| |
| ; Test that fcanonicalize on NaN constants preserves payload bits. |
| ; AMDGPU HW (v_max_f32) quiets SNaN by setting bit 22 only, keeping |
| ; the rest of the payload. QNaN passes through unchanged. |
| |
| ; SNaN 0x7F800001 (payload=0x000001) -> QNaN 0x7FC00001 |
| define amdgpu_kernel void @canonicalize_snan_payload_min_f32(ptr addrspace(1) %out) { |
| ; SDAG-LABEL: canonicalize_snan_payload_min_f32: |
| ; SDAG: ; %bb.0: |
| ; SDAG-NEXT: s_load_dwordx2 s[0:1], s[8:9], 0x0 |
| ; SDAG-NEXT: v_mov_b32_e32 v0, 0 |
| ; SDAG-NEXT: v_mov_b32_e32 v1, 0x7fc00001 |
| ; SDAG-NEXT: s_waitcnt lgkmcnt(0) |
| ; SDAG-NEXT: global_store_dword v0, v1, s[0:1] |
| ; SDAG-NEXT: s_endpgm |
| ; |
| ; GISEL-LABEL: canonicalize_snan_payload_min_f32: |
| ; GISEL: ; %bb.0: |
| ; GISEL-NEXT: s_load_dwordx2 s[0:1], s[8:9], 0x0 |
| ; GISEL-NEXT: v_mov_b32_e32 v0, 0x7f800001 |
| ; GISEL-NEXT: v_max_f32_e32 v0, 0x7f800001, v0 |
| ; GISEL-NEXT: v_mov_b32_e32 v1, 0 |
| ; GISEL-NEXT: s_waitcnt lgkmcnt(0) |
| ; GISEL-NEXT: global_store_dword v1, v0, s[0:1] |
| ; GISEL-NEXT: s_endpgm |
| %canonicalized = call float @llvm.canonicalize.f32(float bitcast (i32 2139095041 to float)) |
| store float %canonicalized, ptr addrspace(1) %out |
| ret void |
| } |
| |
| ; SNaN 0x7F8A5A5A (payload=0x0A5A5A) -> QNaN 0x7FCA5A5A |
| define amdgpu_kernel void @canonicalize_snan_payload_custom_f32(ptr addrspace(1) %out) { |
| ; SDAG-LABEL: canonicalize_snan_payload_custom_f32: |
| ; SDAG: ; %bb.0: |
| ; SDAG-NEXT: s_load_dwordx2 s[0:1], s[8:9], 0x0 |
| ; SDAG-NEXT: v_mov_b32_e32 v0, 0 |
| ; SDAG-NEXT: v_mov_b32_e32 v1, 0x7fca5a5a |
| ; SDAG-NEXT: s_waitcnt lgkmcnt(0) |
| ; SDAG-NEXT: global_store_dword v0, v1, s[0:1] |
| ; SDAG-NEXT: s_endpgm |
| ; |
| ; GISEL-LABEL: canonicalize_snan_payload_custom_f32: |
| ; GISEL: ; %bb.0: |
| ; GISEL-NEXT: s_load_dwordx2 s[0:1], s[8:9], 0x0 |
| ; GISEL-NEXT: v_mov_b32_e32 v0, 0x7f8a5a5a |
| ; GISEL-NEXT: v_max_f32_e32 v0, 0x7f8a5a5a, v0 |
| ; GISEL-NEXT: v_mov_b32_e32 v1, 0 |
| ; GISEL-NEXT: s_waitcnt lgkmcnt(0) |
| ; GISEL-NEXT: global_store_dword v1, v0, s[0:1] |
| ; GISEL-NEXT: s_endpgm |
| %canonicalized = call float @llvm.canonicalize.f32(float bitcast (i32 2139773530 to float)) |
| store float %canonicalized, ptr addrspace(1) %out |
| ret void |
| } |
| |
| ; SNaN 0x7FBFFFFF (payload=0x3FFFFF, max) -> QNaN 0x7FFFFFFF |
| define amdgpu_kernel void @canonicalize_snan_payload_max_f32(ptr addrspace(1) %out) { |
| ; SDAG-LABEL: canonicalize_snan_payload_max_f32: |
| ; SDAG: ; %bb.0: |
| ; SDAG-NEXT: s_load_dwordx2 s[0:1], s[8:9], 0x0 |
| ; SDAG-NEXT: v_mov_b32_e32 v0, 0 |
| ; SDAG-NEXT: v_bfrev_b32_e32 v1, -2 |
| ; SDAG-NEXT: s_waitcnt lgkmcnt(0) |
| ; SDAG-NEXT: global_store_dword v0, v1, s[0:1] |
| ; SDAG-NEXT: s_endpgm |
| ; |
| ; GISEL-LABEL: canonicalize_snan_payload_max_f32: |
| ; GISEL: ; %bb.0: |
| ; GISEL-NEXT: s_load_dwordx2 s[0:1], s[8:9], 0x0 |
| ; GISEL-NEXT: v_mov_b32_e32 v0, 0x7fbfffff |
| ; GISEL-NEXT: v_max_f32_e32 v0, 0x7fbfffff, v0 |
| ; GISEL-NEXT: v_mov_b32_e32 v1, 0 |
| ; GISEL-NEXT: s_waitcnt lgkmcnt(0) |
| ; GISEL-NEXT: global_store_dword v1, v0, s[0:1] |
| ; GISEL-NEXT: s_endpgm |
| %canonicalized = call float @llvm.canonicalize.f32(float bitcast (i32 2143289343 to float)) |
| store float %canonicalized, ptr addrspace(1) %out |
| ret void |
| } |
| |
| ; Negative SNaN 0xFF800001 -> negative QNaN 0xFFC00001 |
| define amdgpu_kernel void @canonicalize_neg_snan_payload_f32(ptr addrspace(1) %out) { |
| ; SDAG-LABEL: canonicalize_neg_snan_payload_f32: |
| ; SDAG: ; %bb.0: |
| ; SDAG-NEXT: s_load_dwordx2 s[0:1], s[8:9], 0x0 |
| ; SDAG-NEXT: v_mov_b32_e32 v0, 0 |
| ; SDAG-NEXT: v_mov_b32_e32 v1, 0xffc00001 |
| ; SDAG-NEXT: s_waitcnt lgkmcnt(0) |
| ; SDAG-NEXT: global_store_dword v0, v1, s[0:1] |
| ; SDAG-NEXT: s_endpgm |
| ; |
| ; GISEL-LABEL: canonicalize_neg_snan_payload_f32: |
| ; GISEL: ; %bb.0: |
| ; GISEL-NEXT: s_load_dwordx2 s[0:1], s[8:9], 0x0 |
| ; GISEL-NEXT: v_mov_b32_e32 v0, 0xff800001 |
| ; GISEL-NEXT: v_max_f32_e32 v0, 0xff800001, v0 |
| ; GISEL-NEXT: v_mov_b32_e32 v1, 0 |
| ; GISEL-NEXT: s_waitcnt lgkmcnt(0) |
| ; GISEL-NEXT: global_store_dword v1, v0, s[0:1] |
| ; GISEL-NEXT: s_endpgm |
| %canonicalized = call float @llvm.canonicalize.f32(float bitcast (i32 -8388607 to float)) |
| store float %canonicalized, ptr addrspace(1) %out |
| ret void |
| } |
| |
| ; QNaN 0x7FCDEF12 (non-default payload) -> unchanged 0x7FCDEF12 |
| define amdgpu_kernel void @canonicalize_qnan_payload_f32(ptr addrspace(1) %out) { |
| ; SDAG-LABEL: canonicalize_qnan_payload_f32: |
| ; SDAG: ; %bb.0: |
| ; SDAG-NEXT: s_load_dwordx2 s[0:1], s[8:9], 0x0 |
| ; SDAG-NEXT: v_mov_b32_e32 v0, 0 |
| ; SDAG-NEXT: v_mov_b32_e32 v1, 0x7fcdef12 |
| ; SDAG-NEXT: s_waitcnt lgkmcnt(0) |
| ; SDAG-NEXT: global_store_dword v0, v1, s[0:1] |
| ; SDAG-NEXT: s_endpgm |
| ; |
| ; GISEL-LABEL: canonicalize_qnan_payload_f32: |
| ; GISEL: ; %bb.0: |
| ; GISEL-NEXT: s_load_dwordx2 s[0:1], s[8:9], 0x0 |
| ; GISEL-NEXT: v_mov_b32_e32 v0, 0x7fcdef12 |
| ; GISEL-NEXT: v_mov_b32_e32 v1, 0 |
| ; GISEL-NEXT: s_waitcnt lgkmcnt(0) |
| ; GISEL-NEXT: global_store_dword v1, v0, s[0:1] |
| ; GISEL-NEXT: s_endpgm |
| %canonicalized = call float @llvm.canonicalize.f32(float bitcast (i32 2144202514 to float)) |
| store float %canonicalized, ptr addrspace(1) %out |
| ret void |
| } |
| |
| declare float @llvm.canonicalize.f32(float) |