[llvm] [AMDGPU] Precommit Tests for 'Fold redundant inf/nan checks into frexp instructions' (PR #214964)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 9 02:02:45 PDT 2026


================
@@ -0,0 +1,792 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=amdgpu9.00-amd-amdhsa < %s | FileCheck -check-prefix=GFX9 %s
+; RUN: llc -mtriple=amdgpu10.30-amd-amdhsa < %s | FileCheck -check-prefix=GFX10 %s
+; RUN: llc -mtriple=amdgpu11.00-amd-amdhsa < %s | FileCheck -check-prefix=GFX11 %s
+; RUN: llc -mtriple=amdgpu9.50-amd-amdhsa < %s | FileCheck -check-prefix=GFX950 %s
+; RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=tahiti < %s | FileCheck -check-prefix=SI %s
+
+; Test that redundant inf/nan checks are folded into frexp instructions.
+; The AMDGPU frexp instructions already return 0 for inf/nan inputs.
+; This optimization should NOT apply on SI (Southern Islands) which has hasFractBug.
+
+; Pattern 1: select (fcmp uno x, 0), 0, (frexp_exp x)
+; NaN check - should fold to just frexp_exp
+define i32 @frexp_nan_clamp_exp_f32(float %x) {
+; GFX9-LABEL: frexp_nan_clamp_exp_f32:
+; GFX9:       ; %bb.0:
+; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:    v_frexp_exp_i32_f32_e32 v1, v0
+; GFX9-NEXT:    v_cmp_o_f32_e32 vcc, v0, v0
+; GFX9-NEXT:    v_cndmask_b32_e32 v0, 0, v1, vcc
+; GFX9-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: frexp_nan_clamp_exp_f32:
+; GFX10:       ; %bb.0:
+; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT:    v_frexp_exp_i32_f32_e32 v1, v0
+; GFX10-NEXT:    v_cmp_o_f32_e32 vcc_lo, v0, v0
+; GFX10-NEXT:    v_cndmask_b32_e32 v0, 0, v1, vcc_lo
+; GFX10-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: frexp_nan_clamp_exp_f32:
+; GFX11:       ; %bb.0:
+; GFX11-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:    v_frexp_exp_i32_f32_e32 v1, v0
+; GFX11-NEXT:    v_cmp_o_f32_e32 vcc_lo, v0, v0
+; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_2)
+; GFX11-NEXT:    v_cndmask_b32_e32 v0, 0, v1, vcc_lo
+; GFX11-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX950-LABEL: frexp_nan_clamp_exp_f32:
+; GFX950:       ; %bb.0:
+; GFX950-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX950-NEXT:    v_frexp_exp_i32_f32_e32 v1, v0
+; GFX950-NEXT:    v_cmp_o_f32_e32 vcc, v0, v0
+; GFX950-NEXT:    s_nop 1
+; GFX950-NEXT:    v_cndmask_b32_e32 v0, 0, v1, vcc
+; GFX950-NEXT:    s_setpc_b64 s[30:31]
+;
+; SI-LABEL: frexp_nan_clamp_exp_f32:
+; SI:       ; %bb.0:
+; SI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SI-NEXT:    s_mov_b32 s4, 0x7f800000
+; SI-NEXT:    v_cmp_lt_f32_e64 s[4:5], |v0|, s4
+; SI-NEXT:    v_cmp_o_f32_e32 vcc, v0, v0
+; SI-NEXT:    v_frexp_exp_i32_f32_e32 v1, v0
+; SI-NEXT:    s_and_b64 vcc, vcc, s[4:5]
+; SI-NEXT:    v_cndmask_b32_e32 v0, 0, v1, vcc
+; SI-NEXT:    s_setpc_b64 s[30:31]
+  %frexp = call {float, i32} @llvm.frexp.f32.i32(float %x)
+  %exp = extractvalue {float, i32} %frexp, 1
+  %is_nan = fcmp uno float %x, 0.0
+  %result = select i1 %is_nan, i32 0, i32 %exp
+  ret i32 %result
+}
+
----------------
arsenm wrote:

 I'd prefer to keep the commuted form cases next to each other; the next one here would be the fcmp ord with the select arms swapped 

https://github.com/llvm/llvm-project/pull/214964


More information about the llvm-commits mailing list