[llvm] cd60bff - CodeGen: Add some additional is_fpclass lowering tests

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 14 22:13:19 PDT 2023


Author: Matt Arsenault
Date: 2023-03-15T01:13:08-04:00
New Revision: cd60bff32966e1bd29f3e0e21d6e0b7276017758

URL: https://github.com/llvm/llvm-project/commit/cd60bff32966e1bd29f3e0e21d6e0b7276017758
DIFF: https://github.com/llvm/llvm-project/commit/cd60bff32966e1bd29f3e0e21d6e0b7276017758.diff

LOG: CodeGen: Add some additional is_fpclass lowering tests

Cover more cases in preparation for making greater use
of fcmp based lowerings. Also add more tests for the inverted
cases. Test iszero | isnan test masks. We should probably just
generate every combination of test masks.

Added: 
    

Modified: 
    llvm/test/CodeGen/AMDGPU/llvm.is.fpclass.f16.ll
    llvm/test/CodeGen/X86/is_fpclass.ll

Removed: 
    


################################################################################
diff  --git a/llvm/test/CodeGen/AMDGPU/llvm.is.fpclass.f16.ll b/llvm/test/CodeGen/AMDGPU/llvm.is.fpclass.f16.ll
index f4072960f7cfe..03d9f77acdf2f 100644
--- a/llvm/test/CodeGen/AMDGPU/llvm.is.fpclass.f16.ll
+++ b/llvm/test/CodeGen/AMDGPU/llvm.is.fpclass.f16.ll
@@ -2464,7 +2464,952 @@ define i1 @not_isnegative_f16(half %x) {
   ret i1 %class
 }
 
+define i1 @iszero_or_nan_f16(half %x) {
+; GFX7SELDAG-LABEL: iszero_or_nan_f16:
+; GFX7SELDAG:       ; %bb.0: ; %entry
+; GFX7SELDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7SELDAG-NEXT:    v_cvt_f16_f32_e32 v0, v0
+; GFX7SELDAG-NEXT:    s_movk_i32 s4, 0x7c00
+; GFX7SELDAG-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7SELDAG-NEXT:    v_cmp_lt_i32_e32 vcc, s4, v0
+; GFX7SELDAG-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v0
+; GFX7SELDAG-NEXT:    s_or_b64 s[4:5], s[4:5], vcc
+; GFX7SELDAG-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX7SELDAG-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX7GLISEL-LABEL: iszero_or_nan_f16:
+; GFX7GLISEL:       ; %bb.0: ; %entry
+; GFX7GLISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7GLISEL-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7GLISEL-NEXT:    v_bfe_u32 v0, v0, 0, 16
+; GFX7GLISEL-NEXT:    v_mov_b32_e32 v1, 0x7c00
+; GFX7GLISEL-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7GLISEL-NEXT:    v_cmp_gt_u32_e64 s[4:5], v0, v1
+; GFX7GLISEL-NEXT:    s_or_b64 s[4:5], vcc, s[4:5]
+; GFX7GLISEL-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX7GLISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX8CHECK-LABEL: iszero_or_nan_f16:
+; GFX8CHECK:       ; %bb.0: ; %entry
+; GFX8CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8CHECK-NEXT:    v_mov_b32_e32 v1, 0x63
+; GFX8CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX8CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX8CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9CHECK-LABEL: iszero_or_nan_f16:
+; GFX9CHECK:       ; %bb.0: ; %entry
+; GFX9CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9CHECK-NEXT:    v_mov_b32_e32 v1, 0x63
+; GFX9CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX9CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX9CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX10CHECK-LABEL: iszero_or_nan_f16:
+; GFX10CHECK:       ; %bb.0: ; %entry
+; GFX10CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX10CHECK-NEXT:    v_cmp_class_f16_e64 s4, v0, 0x63
+; GFX10CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s4
+; GFX10CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11CHECK-LABEL: iszero_or_nan_f16:
+; GFX11CHECK:       ; %bb.0: ; %entry
+; GFX11CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX11CHECK-NEXT:    v_cmp_class_f16_e64 s0, v0, 0x63
+; GFX11CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s0
+; GFX11CHECK-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f16(half %x, i32 99)  ; 0x60|0x3 = "zero|nan"
+  ret i1 %0
+}
+
+define i1 @iszero_or_nan_f_daz(half %x) #0 {
+; GFX7SELDAG-LABEL: iszero_or_nan_f_daz:
+; GFX7SELDAG:       ; %bb.0: ; %entry
+; GFX7SELDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7SELDAG-NEXT:    v_cvt_f16_f32_e32 v0, v0
+; GFX7SELDAG-NEXT:    s_movk_i32 s4, 0x7c00
+; GFX7SELDAG-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7SELDAG-NEXT:    v_cmp_lt_i32_e32 vcc, s4, v0
+; GFX7SELDAG-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v0
+; GFX7SELDAG-NEXT:    s_or_b64 s[4:5], s[4:5], vcc
+; GFX7SELDAG-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX7SELDAG-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX7GLISEL-LABEL: iszero_or_nan_f_daz:
+; GFX7GLISEL:       ; %bb.0: ; %entry
+; GFX7GLISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7GLISEL-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7GLISEL-NEXT:    v_bfe_u32 v0, v0, 0, 16
+; GFX7GLISEL-NEXT:    v_mov_b32_e32 v1, 0x7c00
+; GFX7GLISEL-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7GLISEL-NEXT:    v_cmp_gt_u32_e64 s[4:5], v0, v1
+; GFX7GLISEL-NEXT:    s_or_b64 s[4:5], vcc, s[4:5]
+; GFX7GLISEL-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX7GLISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX8CHECK-LABEL: iszero_or_nan_f_daz:
+; GFX8CHECK:       ; %bb.0: ; %entry
+; GFX8CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8CHECK-NEXT:    v_mov_b32_e32 v1, 0x63
+; GFX8CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX8CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX8CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9CHECK-LABEL: iszero_or_nan_f_daz:
+; GFX9CHECK:       ; %bb.0: ; %entry
+; GFX9CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9CHECK-NEXT:    v_mov_b32_e32 v1, 0x63
+; GFX9CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX9CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX9CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX10CHECK-LABEL: iszero_or_nan_f_daz:
+; GFX10CHECK:       ; %bb.0: ; %entry
+; GFX10CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX10CHECK-NEXT:    v_cmp_class_f16_e64 s4, v0, 0x63
+; GFX10CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s4
+; GFX10CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11CHECK-LABEL: iszero_or_nan_f_daz:
+; GFX11CHECK:       ; %bb.0: ; %entry
+; GFX11CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX11CHECK-NEXT:    v_cmp_class_f16_e64 s0, v0, 0x63
+; GFX11CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s0
+; GFX11CHECK-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f16(half %x, i32 99)  ; 0x60|0x3 = "zero|nan"
+  ret i1 %0
+}
+
+define i1 @iszero_or_nan_f_maybe_daz(half %x) #1 {
+; GFX7SELDAG-LABEL: iszero_or_nan_f_maybe_daz:
+; GFX7SELDAG:       ; %bb.0: ; %entry
+; GFX7SELDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7SELDAG-NEXT:    v_cvt_f16_f32_e32 v0, v0
+; GFX7SELDAG-NEXT:    s_movk_i32 s4, 0x7c00
+; GFX7SELDAG-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7SELDAG-NEXT:    v_cmp_lt_i32_e32 vcc, s4, v0
+; GFX7SELDAG-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v0
+; GFX7SELDAG-NEXT:    s_or_b64 s[4:5], s[4:5], vcc
+; GFX7SELDAG-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX7SELDAG-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX7GLISEL-LABEL: iszero_or_nan_f_maybe_daz:
+; GFX7GLISEL:       ; %bb.0: ; %entry
+; GFX7GLISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7GLISEL-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7GLISEL-NEXT:    v_bfe_u32 v0, v0, 0, 16
+; GFX7GLISEL-NEXT:    v_mov_b32_e32 v1, 0x7c00
+; GFX7GLISEL-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7GLISEL-NEXT:    v_cmp_gt_u32_e64 s[4:5], v0, v1
+; GFX7GLISEL-NEXT:    s_or_b64 s[4:5], vcc, s[4:5]
+; GFX7GLISEL-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX7GLISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX8CHECK-LABEL: iszero_or_nan_f_maybe_daz:
+; GFX8CHECK:       ; %bb.0: ; %entry
+; GFX8CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8CHECK-NEXT:    v_mov_b32_e32 v1, 0x63
+; GFX8CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX8CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX8CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9CHECK-LABEL: iszero_or_nan_f_maybe_daz:
+; GFX9CHECK:       ; %bb.0: ; %entry
+; GFX9CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9CHECK-NEXT:    v_mov_b32_e32 v1, 0x63
+; GFX9CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX9CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX9CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX10CHECK-LABEL: iszero_or_nan_f_maybe_daz:
+; GFX10CHECK:       ; %bb.0: ; %entry
+; GFX10CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX10CHECK-NEXT:    v_cmp_class_f16_e64 s4, v0, 0x63
+; GFX10CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s4
+; GFX10CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11CHECK-LABEL: iszero_or_nan_f_maybe_daz:
+; GFX11CHECK:       ; %bb.0: ; %entry
+; GFX11CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX11CHECK-NEXT:    v_cmp_class_f16_e64 s0, v0, 0x63
+; GFX11CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s0
+; GFX11CHECK-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f16(half %x, i32 99)  ; 0x60|0x3 = "zero|nan"
+  ret i1 %0
+}
+
+define i1 @not_iszero_or_nan_f16(half %x) {
+; GFX7SELDAG-LABEL: not_iszero_or_nan_f16:
+; GFX7SELDAG:       ; %bb.0: ; %entry
+; GFX7SELDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7SELDAG-NEXT:    v_cvt_f16_f32_e32 v0, v0
+; GFX7SELDAG-NEXT:    s_movk_i32 s4, 0x7c00
+; GFX7SELDAG-NEXT:    s_movk_i32 s6, 0x7800
+; GFX7SELDAG-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7SELDAG-NEXT:    v_cmp_eq_u32_e32 vcc, s4, v0
+; GFX7SELDAG-NEXT:    v_add_i32_e64 v1, s[4:5], -1, v0
+; GFX7SELDAG-NEXT:    s_movk_i32 s4, 0x3ff
+; GFX7SELDAG-NEXT:    v_cmp_gt_u32_e64 s[4:5], s4, v1
+; GFX7SELDAG-NEXT:    s_or_b64 s[4:5], vcc, s[4:5]
+; GFX7SELDAG-NEXT:    v_add_i32_e32 v0, vcc, 0xfffffc00, v0
+; GFX7SELDAG-NEXT:    v_and_b32_e32 v0, 0xffff, v0
+; GFX7SELDAG-NEXT:    v_cmp_gt_u32_e32 vcc, s6, v0
+; GFX7SELDAG-NEXT:    s_or_b64 s[4:5], s[4:5], vcc
+; GFX7SELDAG-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX7SELDAG-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX7GLISEL-LABEL: not_iszero_or_nan_f16:
+; GFX7GLISEL:       ; %bb.0: ; %entry
+; GFX7GLISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7GLISEL-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7GLISEL-NEXT:    v_bfe_u32 v1, v0, 0, 16
+; GFX7GLISEL-NEXT:    v_mov_b32_e32 v2, 0x7c00
+; GFX7GLISEL-NEXT:    v_cmp_eq_u32_e32 vcc, v1, v2
+; GFX7GLISEL-NEXT:    v_subrev_i32_e64 v1, s[4:5], 1, v0
+; GFX7GLISEL-NEXT:    v_and_b32_e32 v1, 0xffff, v1
+; GFX7GLISEL-NEXT:    v_mov_b32_e32 v2, 0x3ff
+; GFX7GLISEL-NEXT:    v_cmp_lt_u32_e64 s[4:5], v1, v2
+; GFX7GLISEL-NEXT:    s_or_b64 s[4:5], vcc, s[4:5]
+; GFX7GLISEL-NEXT:    v_subrev_i32_e32 v0, vcc, 0x400, v0
+; GFX7GLISEL-NEXT:    v_and_b32_e32 v0, 0xffff, v0
+; GFX7GLISEL-NEXT:    v_mov_b32_e32 v1, 0x7800
+; GFX7GLISEL-NEXT:    v_cmp_lt_u32_e32 vcc, v0, v1
+; GFX7GLISEL-NEXT:    s_or_b64 s[4:5], s[4:5], vcc
+; GFX7GLISEL-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX7GLISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX8CHECK-LABEL: not_iszero_or_nan_f16:
+; GFX8CHECK:       ; %bb.0: ; %entry
+; GFX8CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8CHECK-NEXT:    v_mov_b32_e32 v1, 0x39c
+; GFX8CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX8CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX8CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9CHECK-LABEL: not_iszero_or_nan_f16:
+; GFX9CHECK:       ; %bb.0: ; %entry
+; GFX9CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9CHECK-NEXT:    v_mov_b32_e32 v1, 0x39c
+; GFX9CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX9CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX9CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX10CHECK-LABEL: not_iszero_or_nan_f16:
+; GFX10CHECK:       ; %bb.0: ; %entry
+; GFX10CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX10CHECK-NEXT:    v_cmp_class_f16_e64 s4, v0, 0x39c
+; GFX10CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s4
+; GFX10CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11CHECK-LABEL: not_iszero_or_nan_f16:
+; GFX11CHECK:       ; %bb.0: ; %entry
+; GFX11CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX11CHECK-NEXT:    v_cmp_class_f16_e64 s0, v0, 0x39c
+; GFX11CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s0
+; GFX11CHECK-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f16(half %x, i32 924)  ; ~0x60 = "~(zero|nan)"
+  ret i1 %0
+}
+
+define i1 @not_iszero_or_nan_f_daz(half %x) #0 {
+; GFX7SELDAG-LABEL: not_iszero_or_nan_f_daz:
+; GFX7SELDAG:       ; %bb.0: ; %entry
+; GFX7SELDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7SELDAG-NEXT:    v_cvt_f16_f32_e32 v0, v0
+; GFX7SELDAG-NEXT:    s_movk_i32 s4, 0x7c00
+; GFX7SELDAG-NEXT:    s_movk_i32 s6, 0x7800
+; GFX7SELDAG-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7SELDAG-NEXT:    v_cmp_eq_u32_e32 vcc, s4, v0
+; GFX7SELDAG-NEXT:    v_add_i32_e64 v1, s[4:5], -1, v0
+; GFX7SELDAG-NEXT:    s_movk_i32 s4, 0x3ff
+; GFX7SELDAG-NEXT:    v_cmp_gt_u32_e64 s[4:5], s4, v1
+; GFX7SELDAG-NEXT:    s_or_b64 s[4:5], vcc, s[4:5]
+; GFX7SELDAG-NEXT:    v_add_i32_e32 v0, vcc, 0xfffffc00, v0
+; GFX7SELDAG-NEXT:    v_and_b32_e32 v0, 0xffff, v0
+; GFX7SELDAG-NEXT:    v_cmp_gt_u32_e32 vcc, s6, v0
+; GFX7SELDAG-NEXT:    s_or_b64 s[4:5], s[4:5], vcc
+; GFX7SELDAG-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX7SELDAG-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX7GLISEL-LABEL: not_iszero_or_nan_f_daz:
+; GFX7GLISEL:       ; %bb.0: ; %entry
+; GFX7GLISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7GLISEL-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7GLISEL-NEXT:    v_bfe_u32 v1, v0, 0, 16
+; GFX7GLISEL-NEXT:    v_mov_b32_e32 v2, 0x7c00
+; GFX7GLISEL-NEXT:    v_cmp_eq_u32_e32 vcc, v1, v2
+; GFX7GLISEL-NEXT:    v_subrev_i32_e64 v1, s[4:5], 1, v0
+; GFX7GLISEL-NEXT:    v_and_b32_e32 v1, 0xffff, v1
+; GFX7GLISEL-NEXT:    v_mov_b32_e32 v2, 0x3ff
+; GFX7GLISEL-NEXT:    v_cmp_lt_u32_e64 s[4:5], v1, v2
+; GFX7GLISEL-NEXT:    s_or_b64 s[4:5], vcc, s[4:5]
+; GFX7GLISEL-NEXT:    v_subrev_i32_e32 v0, vcc, 0x400, v0
+; GFX7GLISEL-NEXT:    v_and_b32_e32 v0, 0xffff, v0
+; GFX7GLISEL-NEXT:    v_mov_b32_e32 v1, 0x7800
+; GFX7GLISEL-NEXT:    v_cmp_lt_u32_e32 vcc, v0, v1
+; GFX7GLISEL-NEXT:    s_or_b64 s[4:5], s[4:5], vcc
+; GFX7GLISEL-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX7GLISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX8CHECK-LABEL: not_iszero_or_nan_f_daz:
+; GFX8CHECK:       ; %bb.0: ; %entry
+; GFX8CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8CHECK-NEXT:    v_mov_b32_e32 v1, 0x39c
+; GFX8CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX8CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX8CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9CHECK-LABEL: not_iszero_or_nan_f_daz:
+; GFX9CHECK:       ; %bb.0: ; %entry
+; GFX9CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9CHECK-NEXT:    v_mov_b32_e32 v1, 0x39c
+; GFX9CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX9CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX9CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX10CHECK-LABEL: not_iszero_or_nan_f_daz:
+; GFX10CHECK:       ; %bb.0: ; %entry
+; GFX10CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX10CHECK-NEXT:    v_cmp_class_f16_e64 s4, v0, 0x39c
+; GFX10CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s4
+; GFX10CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11CHECK-LABEL: not_iszero_or_nan_f_daz:
+; GFX11CHECK:       ; %bb.0: ; %entry
+; GFX11CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX11CHECK-NEXT:    v_cmp_class_f16_e64 s0, v0, 0x39c
+; GFX11CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s0
+; GFX11CHECK-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f16(half %x, i32 924)  ; ~(0x60|0x3) = "~(zero|nan)"
+  ret i1 %0
+}
+
+define i1 @not_iszero_or_nan_f_maybe_daz(half %x) #1 {
+; GFX7SELDAG-LABEL: not_iszero_or_nan_f_maybe_daz:
+; GFX7SELDAG:       ; %bb.0: ; %entry
+; GFX7SELDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7SELDAG-NEXT:    v_cvt_f16_f32_e32 v0, v0
+; GFX7SELDAG-NEXT:    s_movk_i32 s4, 0x7c00
+; GFX7SELDAG-NEXT:    s_movk_i32 s6, 0x7800
+; GFX7SELDAG-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7SELDAG-NEXT:    v_cmp_eq_u32_e32 vcc, s4, v0
+; GFX7SELDAG-NEXT:    v_add_i32_e64 v1, s[4:5], -1, v0
+; GFX7SELDAG-NEXT:    s_movk_i32 s4, 0x3ff
+; GFX7SELDAG-NEXT:    v_cmp_gt_u32_e64 s[4:5], s4, v1
+; GFX7SELDAG-NEXT:    s_or_b64 s[4:5], vcc, s[4:5]
+; GFX7SELDAG-NEXT:    v_add_i32_e32 v0, vcc, 0xfffffc00, v0
+; GFX7SELDAG-NEXT:    v_and_b32_e32 v0, 0xffff, v0
+; GFX7SELDAG-NEXT:    v_cmp_gt_u32_e32 vcc, s6, v0
+; GFX7SELDAG-NEXT:    s_or_b64 s[4:5], s[4:5], vcc
+; GFX7SELDAG-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX7SELDAG-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX7GLISEL-LABEL: not_iszero_or_nan_f_maybe_daz:
+; GFX7GLISEL:       ; %bb.0: ; %entry
+; GFX7GLISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7GLISEL-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7GLISEL-NEXT:    v_bfe_u32 v1, v0, 0, 16
+; GFX7GLISEL-NEXT:    v_mov_b32_e32 v2, 0x7c00
+; GFX7GLISEL-NEXT:    v_cmp_eq_u32_e32 vcc, v1, v2
+; GFX7GLISEL-NEXT:    v_subrev_i32_e64 v1, s[4:5], 1, v0
+; GFX7GLISEL-NEXT:    v_and_b32_e32 v1, 0xffff, v1
+; GFX7GLISEL-NEXT:    v_mov_b32_e32 v2, 0x3ff
+; GFX7GLISEL-NEXT:    v_cmp_lt_u32_e64 s[4:5], v1, v2
+; GFX7GLISEL-NEXT:    s_or_b64 s[4:5], vcc, s[4:5]
+; GFX7GLISEL-NEXT:    v_subrev_i32_e32 v0, vcc, 0x400, v0
+; GFX7GLISEL-NEXT:    v_and_b32_e32 v0, 0xffff, v0
+; GFX7GLISEL-NEXT:    v_mov_b32_e32 v1, 0x7800
+; GFX7GLISEL-NEXT:    v_cmp_lt_u32_e32 vcc, v0, v1
+; GFX7GLISEL-NEXT:    s_or_b64 s[4:5], s[4:5], vcc
+; GFX7GLISEL-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX7GLISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX8CHECK-LABEL: not_iszero_or_nan_f_maybe_daz:
+; GFX8CHECK:       ; %bb.0: ; %entry
+; GFX8CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8CHECK-NEXT:    v_mov_b32_e32 v1, 0x39c
+; GFX8CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX8CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX8CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9CHECK-LABEL: not_iszero_or_nan_f_maybe_daz:
+; GFX9CHECK:       ; %bb.0: ; %entry
+; GFX9CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9CHECK-NEXT:    v_mov_b32_e32 v1, 0x39c
+; GFX9CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX9CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX9CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX10CHECK-LABEL: not_iszero_or_nan_f_maybe_daz:
+; GFX10CHECK:       ; %bb.0: ; %entry
+; GFX10CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX10CHECK-NEXT:    v_cmp_class_f16_e64 s4, v0, 0x39c
+; GFX10CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s4
+; GFX10CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11CHECK-LABEL: not_iszero_or_nan_f_maybe_daz:
+; GFX11CHECK:       ; %bb.0: ; %entry
+; GFX11CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX11CHECK-NEXT:    v_cmp_class_f16_e64 s0, v0, 0x39c
+; GFX11CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s0
+; GFX11CHECK-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f16(half %x, i32 924)  ; ~(0x60|0x3) = "~(zero|nan)"
+  ret i1 %0
+}
+
+define i1 @iszero_or_qnan_f16(half %x) {
+; GFX7SELDAG-LABEL: iszero_or_qnan_f16:
+; GFX7SELDAG:       ; %bb.0: ; %entry
+; GFX7SELDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7SELDAG-NEXT:    v_cvt_f16_f32_e32 v0, v0
+; GFX7SELDAG-NEXT:    s_movk_i32 s4, 0x7dff
+; GFX7SELDAG-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7SELDAG-NEXT:    v_cmp_lt_i32_e32 vcc, s4, v0
+; GFX7SELDAG-NEXT:    v_cmp_eq_u32_e64 s[4:5], 0, v0
+; GFX7SELDAG-NEXT:    s_or_b64 s[4:5], s[4:5], vcc
+; GFX7SELDAG-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX7SELDAG-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX7GLISEL-LABEL: iszero_or_qnan_f16:
+; GFX7GLISEL:       ; %bb.0: ; %entry
+; GFX7GLISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7GLISEL-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7GLISEL-NEXT:    v_bfe_u32 v0, v0, 0, 16
+; GFX7GLISEL-NEXT:    v_mov_b32_e32 v1, 0x7e00
+; GFX7GLISEL-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7GLISEL-NEXT:    v_cmp_ge_u32_e64 s[4:5], v0, v1
+; GFX7GLISEL-NEXT:    s_or_b64 s[4:5], vcc, s[4:5]
+; GFX7GLISEL-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX7GLISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX8CHECK-LABEL: iszero_or_qnan_f16:
+; GFX8CHECK:       ; %bb.0: ; %entry
+; GFX8CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8CHECK-NEXT:    v_mov_b32_e32 v1, 0x62
+; GFX8CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX8CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX8CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9CHECK-LABEL: iszero_or_qnan_f16:
+; GFX9CHECK:       ; %bb.0: ; %entry
+; GFX9CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9CHECK-NEXT:    v_mov_b32_e32 v1, 0x62
+; GFX9CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX9CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX9CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX10CHECK-LABEL: iszero_or_qnan_f16:
+; GFX10CHECK:       ; %bb.0: ; %entry
+; GFX10CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX10CHECK-NEXT:    v_cmp_class_f16_e64 s4, v0, 0x62
+; GFX10CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s4
+; GFX10CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11CHECK-LABEL: iszero_or_qnan_f16:
+; GFX11CHECK:       ; %bb.0: ; %entry
+; GFX11CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX11CHECK-NEXT:    v_cmp_class_f16_e64 s0, v0, 0x62
+; GFX11CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s0
+; GFX11CHECK-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f16(half %x, i32 98)  ; 0x60|0x2 = "zero|qnan"
+  ret i1 %0
+}
+
+define i1 @iszero_or_snan_f16(half %x) {
+; GFX7SELDAG-LABEL: iszero_or_snan_f16:
+; GFX7SELDAG:       ; %bb.0: ; %entry
+; GFX7SELDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7SELDAG-NEXT:    v_cvt_f16_f32_e32 v0, v0
+; GFX7SELDAG-NEXT:    s_movk_i32 s4, 0x7e00
+; GFX7SELDAG-NEXT:    s_movk_i32 s5, 0x7c00
+; GFX7SELDAG-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7SELDAG-NEXT:    v_cmp_gt_i32_e32 vcc, s4, v0
+; GFX7SELDAG-NEXT:    v_cmp_lt_i32_e64 s[4:5], s5, v0
+; GFX7SELDAG-NEXT:    s_and_b64 s[4:5], s[4:5], vcc
+; GFX7SELDAG-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7SELDAG-NEXT:    s_or_b64 s[4:5], vcc, s[4:5]
+; GFX7SELDAG-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX7SELDAG-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX7GLISEL-LABEL: iszero_or_snan_f16:
+; GFX7GLISEL:       ; %bb.0: ; %entry
+; GFX7GLISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7GLISEL-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7GLISEL-NEXT:    v_bfe_u32 v0, v0, 0, 16
+; GFX7GLISEL-NEXT:    v_mov_b32_e32 v1, 0x7c00
+; GFX7GLISEL-NEXT:    v_cmp_gt_u32_e64 s[4:5], v0, v1
+; GFX7GLISEL-NEXT:    v_mov_b32_e32 v1, 0x7e00
+; GFX7GLISEL-NEXT:    v_cmp_lt_u32_e64 s[6:7], v0, v1
+; GFX7GLISEL-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v0
+; GFX7GLISEL-NEXT:    s_and_b64 s[4:5], s[4:5], s[6:7]
+; GFX7GLISEL-NEXT:    s_or_b64 s[4:5], vcc, s[4:5]
+; GFX7GLISEL-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX7GLISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX8CHECK-LABEL: iszero_or_snan_f16:
+; GFX8CHECK:       ; %bb.0: ; %entry
+; GFX8CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8CHECK-NEXT:    v_mov_b32_e32 v1, 0x61
+; GFX8CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX8CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX8CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9CHECK-LABEL: iszero_or_snan_f16:
+; GFX9CHECK:       ; %bb.0: ; %entry
+; GFX9CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9CHECK-NEXT:    v_mov_b32_e32 v1, 0x61
+; GFX9CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX9CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX9CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX10CHECK-LABEL: iszero_or_snan_f16:
+; GFX10CHECK:       ; %bb.0: ; %entry
+; GFX10CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX10CHECK-NEXT:    v_cmp_class_f16_e64 s4, v0, 0x61
+; GFX10CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s4
+; GFX10CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11CHECK-LABEL: iszero_or_snan_f16:
+; GFX11CHECK:       ; %bb.0: ; %entry
+; GFX11CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX11CHECK-NEXT:    v_cmp_class_f16_e64 s0, v0, 0x61
+; GFX11CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s0
+; GFX11CHECK-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f16(half %x, i32 97)  ; 0x60|0x1 = "zero|snan"
+  ret i1 %0
+}
+
+define i1 @not_iszero_or_qnan_f16(half %x) {
+; GFX7SELDAG-LABEL: not_iszero_or_qnan_f16:
+; GFX7SELDAG:       ; %bb.0: ; %entry
+; GFX7SELDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7SELDAG-NEXT:    v_cvt_f16_f32_e32 v0, v0
+; GFX7SELDAG-NEXT:    s_movk_i32 s4, 0x7e00
+; GFX7SELDAG-NEXT:    s_movk_i32 s6, 0x7c00
+; GFX7SELDAG-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7SELDAG-NEXT:    v_cmp_gt_i32_e32 vcc, s4, v0
+; GFX7SELDAG-NEXT:    v_cmp_lt_i32_e64 s[4:5], s6, v0
+; GFX7SELDAG-NEXT:    s_and_b64 s[4:5], s[4:5], vcc
+; GFX7SELDAG-NEXT:    v_cmp_eq_u32_e32 vcc, s6, v0
+; GFX7SELDAG-NEXT:    s_or_b64 s[4:5], vcc, s[4:5]
+; GFX7SELDAG-NEXT:    v_add_i32_e32 v1, vcc, -1, v0
+; GFX7SELDAG-NEXT:    s_movk_i32 s6, 0x3ff
+; GFX7SELDAG-NEXT:    v_cmp_gt_u32_e32 vcc, s6, v1
+; GFX7SELDAG-NEXT:    s_or_b64 s[4:5], s[4:5], vcc
+; GFX7SELDAG-NEXT:    v_add_i32_e32 v0, vcc, 0xfffffc00, v0
+; GFX7SELDAG-NEXT:    v_and_b32_e32 v0, 0xffff, v0
+; GFX7SELDAG-NEXT:    s_movk_i32 s6, 0x7800
+; GFX7SELDAG-NEXT:    v_cmp_gt_u32_e32 vcc, s6, v0
+; GFX7SELDAG-NEXT:    s_or_b64 s[4:5], s[4:5], vcc
+; GFX7SELDAG-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX7SELDAG-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX7GLISEL-LABEL: not_iszero_or_qnan_f16:
+; GFX7GLISEL:       ; %bb.0: ; %entry
+; GFX7GLISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7GLISEL-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7GLISEL-NEXT:    v_bfe_u32 v1, v0, 0, 16
+; GFX7GLISEL-NEXT:    s_movk_i32 s4, 0x7c00
+; GFX7GLISEL-NEXT:    v_mov_b32_e32 v2, 0x7e00
+; GFX7GLISEL-NEXT:    v_cmp_eq_u32_e32 vcc, s4, v1
+; GFX7GLISEL-NEXT:    v_cmp_lt_u32_e64 s[4:5], s4, v1
+; GFX7GLISEL-NEXT:    v_cmp_lt_u32_e64 s[6:7], v1, v2
+; GFX7GLISEL-NEXT:    s_and_b64 s[4:5], s[4:5], s[6:7]
+; GFX7GLISEL-NEXT:    s_or_b64 s[4:5], vcc, s[4:5]
+; GFX7GLISEL-NEXT:    v_subrev_i32_e32 v1, vcc, 1, v0
+; GFX7GLISEL-NEXT:    v_and_b32_e32 v1, 0xffff, v1
+; GFX7GLISEL-NEXT:    v_mov_b32_e32 v2, 0x3ff
+; GFX7GLISEL-NEXT:    v_cmp_lt_u32_e32 vcc, v1, v2
+; GFX7GLISEL-NEXT:    s_or_b64 s[4:5], s[4:5], vcc
+; GFX7GLISEL-NEXT:    v_subrev_i32_e32 v0, vcc, 0x400, v0
+; GFX7GLISEL-NEXT:    v_and_b32_e32 v0, 0xffff, v0
+; GFX7GLISEL-NEXT:    v_mov_b32_e32 v1, 0x7800
+; GFX7GLISEL-NEXT:    v_cmp_lt_u32_e32 vcc, v0, v1
+; GFX7GLISEL-NEXT:    s_or_b64 s[4:5], s[4:5], vcc
+; GFX7GLISEL-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX7GLISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX8CHECK-LABEL: not_iszero_or_qnan_f16:
+; GFX8CHECK:       ; %bb.0: ; %entry
+; GFX8CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8CHECK-NEXT:    v_mov_b32_e32 v1, 0x39d
+; GFX8CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX8CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX8CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9CHECK-LABEL: not_iszero_or_qnan_f16:
+; GFX9CHECK:       ; %bb.0: ; %entry
+; GFX9CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9CHECK-NEXT:    v_mov_b32_e32 v1, 0x39d
+; GFX9CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX9CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX9CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX10CHECK-LABEL: not_iszero_or_qnan_f16:
+; GFX10CHECK:       ; %bb.0: ; %entry
+; GFX10CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX10CHECK-NEXT:    v_cmp_class_f16_e64 s4, v0, 0x39d
+; GFX10CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s4
+; GFX10CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11CHECK-LABEL: not_iszero_or_qnan_f16:
+; GFX11CHECK:       ; %bb.0: ; %entry
+; GFX11CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX11CHECK-NEXT:    v_cmp_class_f16_e64 s0, v0, 0x39d
+; GFX11CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s0
+; GFX11CHECK-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f16(half %x, i32 925)  ; ~(0x60|0x2) = "~(zero|qnan)"
+  ret i1 %0
+}
+
+define i1 @not_iszero_or_snan_f16(half %x) {
+; GFX7SELDAG-LABEL: not_iszero_or_snan_f16:
+; GFX7SELDAG:       ; %bb.0: ; %entry
+; GFX7SELDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7SELDAG-NEXT:    v_cvt_f16_f32_e32 v0, v0
+; GFX7SELDAG-NEXT:    s_movk_i32 s4, 0x7dff
+; GFX7SELDAG-NEXT:    s_movk_i32 s5, 0x7c00
+; GFX7SELDAG-NEXT:    s_movk_i32 s6, 0x3ff
+; GFX7SELDAG-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7SELDAG-NEXT:    v_cmp_lt_i32_e32 vcc, s4, v0
+; GFX7SELDAG-NEXT:    v_cmp_eq_u32_e64 s[4:5], s5, v0
+; GFX7SELDAG-NEXT:    s_or_b64 s[4:5], s[4:5], vcc
+; GFX7SELDAG-NEXT:    v_add_i32_e32 v1, vcc, -1, v0
+; GFX7SELDAG-NEXT:    v_cmp_gt_u32_e32 vcc, s6, v1
+; GFX7SELDAG-NEXT:    s_or_b64 s[4:5], s[4:5], vcc
+; GFX7SELDAG-NEXT:    v_add_i32_e32 v0, vcc, 0xfffffc00, v0
+; GFX7SELDAG-NEXT:    v_and_b32_e32 v0, 0xffff, v0
+; GFX7SELDAG-NEXT:    s_movk_i32 s6, 0x7800
+; GFX7SELDAG-NEXT:    v_cmp_gt_u32_e32 vcc, s6, v0
+; GFX7SELDAG-NEXT:    s_or_b64 s[4:5], s[4:5], vcc
+; GFX7SELDAG-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX7SELDAG-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX7GLISEL-LABEL: not_iszero_or_snan_f16:
+; GFX7GLISEL:       ; %bb.0: ; %entry
+; GFX7GLISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7GLISEL-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7GLISEL-NEXT:    v_bfe_u32 v1, v0, 0, 16
+; GFX7GLISEL-NEXT:    v_mov_b32_e32 v2, 0x7c00
+; GFX7GLISEL-NEXT:    v_cmp_eq_u32_e32 vcc, v1, v2
+; GFX7GLISEL-NEXT:    v_mov_b32_e32 v2, 0x7e00
+; GFX7GLISEL-NEXT:    v_cmp_ge_u32_e64 s[4:5], v1, v2
+; GFX7GLISEL-NEXT:    s_or_b64 s[4:5], vcc, s[4:5]
+; GFX7GLISEL-NEXT:    v_subrev_i32_e32 v1, vcc, 1, v0
+; GFX7GLISEL-NEXT:    v_and_b32_e32 v1, 0xffff, v1
+; GFX7GLISEL-NEXT:    v_mov_b32_e32 v2, 0x3ff
+; GFX7GLISEL-NEXT:    v_cmp_lt_u32_e32 vcc, v1, v2
+; GFX7GLISEL-NEXT:    s_or_b64 s[4:5], s[4:5], vcc
+; GFX7GLISEL-NEXT:    v_subrev_i32_e32 v0, vcc, 0x400, v0
+; GFX7GLISEL-NEXT:    v_and_b32_e32 v0, 0xffff, v0
+; GFX7GLISEL-NEXT:    v_mov_b32_e32 v1, 0x7800
+; GFX7GLISEL-NEXT:    v_cmp_lt_u32_e32 vcc, v0, v1
+; GFX7GLISEL-NEXT:    s_or_b64 s[4:5], s[4:5], vcc
+; GFX7GLISEL-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX7GLISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX8CHECK-LABEL: not_iszero_or_snan_f16:
+; GFX8CHECK:       ; %bb.0: ; %entry
+; GFX8CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8CHECK-NEXT:    v_mov_b32_e32 v1, 0x39e
+; GFX8CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX8CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX8CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9CHECK-LABEL: not_iszero_or_snan_f16:
+; GFX9CHECK:       ; %bb.0: ; %entry
+; GFX9CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9CHECK-NEXT:    v_mov_b32_e32 v1, 0x39e
+; GFX9CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX9CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX9CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX10CHECK-LABEL: not_iszero_or_snan_f16:
+; GFX10CHECK:       ; %bb.0: ; %entry
+; GFX10CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX10CHECK-NEXT:    v_cmp_class_f16_e64 s4, v0, 0x39e
+; GFX10CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s4
+; GFX10CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11CHECK-LABEL: not_iszero_or_snan_f16:
+; GFX11CHECK:       ; %bb.0: ; %entry
+; GFX11CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX11CHECK-NEXT:    v_cmp_class_f16_e64 s0, v0, 0x39e
+; GFX11CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s0
+; GFX11CHECK-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f16(half %x, i32 926)  ; ~(0x60|0x1) = "~(zero|snan)"
+  ret i1 %0
+}
+
+define i1 @isinf_or_nan_f16(half %x) {
+; GFX7SELDAG-LABEL: isinf_or_nan_f16:
+; GFX7SELDAG:       ; %bb.0: ; %entry
+; GFX7SELDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7SELDAG-NEXT:    v_cvt_f16_f32_e32 v0, v0
+; GFX7SELDAG-NEXT:    s_movk_i32 s4, 0x7bff
+; GFX7SELDAG-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7SELDAG-NEXT:    v_cmp_lt_i32_e32 vcc, s4, v0
+; GFX7SELDAG-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX7SELDAG-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX7GLISEL-LABEL: isinf_or_nan_f16:
+; GFX7GLISEL:       ; %bb.0: ; %entry
+; GFX7GLISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7GLISEL-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7GLISEL-NEXT:    v_bfe_u32 v0, v0, 0, 16
+; GFX7GLISEL-NEXT:    s_movk_i32 s4, 0x7c00
+; GFX7GLISEL-NEXT:    v_cmp_eq_u32_e32 vcc, s4, v0
+; GFX7GLISEL-NEXT:    v_cmp_lt_u32_e64 s[4:5], s4, v0
+; GFX7GLISEL-NEXT:    s_or_b64 s[4:5], vcc, s[4:5]
+; GFX7GLISEL-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX7GLISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX8CHECK-LABEL: isinf_or_nan_f16:
+; GFX8CHECK:       ; %bb.0: ; %entry
+; GFX8CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8CHECK-NEXT:    v_mov_b32_e32 v1, 0x207
+; GFX8CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX8CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX8CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9CHECK-LABEL: isinf_or_nan_f16:
+; GFX9CHECK:       ; %bb.0: ; %entry
+; GFX9CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9CHECK-NEXT:    v_mov_b32_e32 v1, 0x207
+; GFX9CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX9CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX9CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX10CHECK-LABEL: isinf_or_nan_f16:
+; GFX10CHECK:       ; %bb.0: ; %entry
+; GFX10CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX10CHECK-NEXT:    v_cmp_class_f16_e64 s4, v0, 0x207
+; GFX10CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s4
+; GFX10CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11CHECK-LABEL: isinf_or_nan_f16:
+; GFX11CHECK:       ; %bb.0: ; %entry
+; GFX11CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX11CHECK-NEXT:    v_cmp_class_f16_e64 s0, v0, 0x207
+; GFX11CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s0
+; GFX11CHECK-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f16(half %x, i32 519)  ; 0x204|0x3 = "inf|nan"
+  ret i1 %0
+}
+
+define i1 @not_isinf_or_nan_f16(half %x) {
+; GFX7SELDAG-LABEL: not_isinf_or_nan_f16:
+; GFX7SELDAG:       ; %bb.0: ; %entry
+; GFX7SELDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7SELDAG-NEXT:    v_cvt_f16_f32_e32 v0, v0
+; GFX7SELDAG-NEXT:    s_movk_i32 s4, 0x7c00
+; GFX7SELDAG-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7SELDAG-NEXT:    v_cmp_gt_i32_e32 vcc, s4, v0
+; GFX7SELDAG-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX7SELDAG-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX7GLISEL-LABEL: not_isinf_or_nan_f16:
+; GFX7GLISEL:       ; %bb.0: ; %entry
+; GFX7GLISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7GLISEL-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7GLISEL-NEXT:    v_bfe_u32 v0, v0, 0, 16
+; GFX7GLISEL-NEXT:    v_mov_b32_e32 v1, 0x7c00
+; GFX7GLISEL-NEXT:    v_cmp_lt_u32_e32 vcc, v0, v1
+; GFX7GLISEL-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX7GLISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX8CHECK-LABEL: not_isinf_or_nan_f16:
+; GFX8CHECK:       ; %bb.0: ; %entry
+; GFX8CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8CHECK-NEXT:    v_mov_b32_e32 v1, 0x1f8
+; GFX8CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX8CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX8CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9CHECK-LABEL: not_isinf_or_nan_f16:
+; GFX9CHECK:       ; %bb.0: ; %entry
+; GFX9CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9CHECK-NEXT:    v_mov_b32_e32 v1, 0x1f8
+; GFX9CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX9CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX9CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX10CHECK-LABEL: not_isinf_or_nan_f16:
+; GFX10CHECK:       ; %bb.0: ; %entry
+; GFX10CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX10CHECK-NEXT:    v_cmp_class_f16_e64 s4, v0, 0x1f8
+; GFX10CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s4
+; GFX10CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11CHECK-LABEL: not_isinf_or_nan_f16:
+; GFX11CHECK:       ; %bb.0: ; %entry
+; GFX11CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX11CHECK-NEXT:    v_cmp_class_f16_e64 s0, v0, 0x1f8
+; GFX11CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s0
+; GFX11CHECK-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f16(half %x, i32 504)  ; ~(0x204|0x3) = "~(inf|nan)"
+  ret i1 %0
+}
+
+define i1 @isfinite_or_nan_f(half %x) {
+; GFX7SELDAG-LABEL: isfinite_or_nan_f:
+; GFX7SELDAG:       ; %bb.0: ; %entry
+; GFX7SELDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7SELDAG-NEXT:    v_cvt_f16_f32_e32 v0, v0
+; GFX7SELDAG-NEXT:    s_movk_i32 s4, 0x7c00
+; GFX7SELDAG-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7SELDAG-NEXT:    v_cmp_ne_u32_e32 vcc, s4, v0
+; GFX7SELDAG-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX7SELDAG-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX7GLISEL-LABEL: isfinite_or_nan_f:
+; GFX7GLISEL:       ; %bb.0: ; %entry
+; GFX7GLISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7GLISEL-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7GLISEL-NEXT:    v_bfe_u32 v0, v0, 0, 16
+; GFX7GLISEL-NEXT:    s_movk_i32 s4, 0x7c00
+; GFX7GLISEL-NEXT:    v_cmp_gt_u32_e32 vcc, s4, v0
+; GFX7GLISEL-NEXT:    v_cmp_lt_u32_e64 s[4:5], s4, v0
+; GFX7GLISEL-NEXT:    s_or_b64 s[4:5], vcc, s[4:5]
+; GFX7GLISEL-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s[4:5]
+; GFX7GLISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX8CHECK-LABEL: isfinite_or_nan_f:
+; GFX8CHECK:       ; %bb.0: ; %entry
+; GFX8CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8CHECK-NEXT:    v_mov_b32_e32 v1, 0x1fb
+; GFX8CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX8CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX8CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9CHECK-LABEL: isfinite_or_nan_f:
+; GFX9CHECK:       ; %bb.0: ; %entry
+; GFX9CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9CHECK-NEXT:    v_mov_b32_e32 v1, 0x1fb
+; GFX9CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX9CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX9CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX10CHECK-LABEL: isfinite_or_nan_f:
+; GFX10CHECK:       ; %bb.0: ; %entry
+; GFX10CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX10CHECK-NEXT:    v_cmp_class_f16_e64 s4, v0, 0x1fb
+; GFX10CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s4
+; GFX10CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11CHECK-LABEL: isfinite_or_nan_f:
+; GFX11CHECK:       ; %bb.0: ; %entry
+; GFX11CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX11CHECK-NEXT:    v_cmp_class_f16_e64 s0, v0, 0x1fb
+; GFX11CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s0
+; GFX11CHECK-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f16(half %x, i32 507)  ; 0x1f8|0x3 = "finite|nan"
+  ret i1 %0
+}
+
+define i1 @not_isfinite_or_nan_f(half %x) {
+; GFX7SELDAG-LABEL: not_isfinite_or_nan_f:
+; GFX7SELDAG:       ; %bb.0: ; %entry
+; GFX7SELDAG-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7SELDAG-NEXT:    v_cvt_f16_f32_e32 v0, v0
+; GFX7SELDAG-NEXT:    s_movk_i32 s4, 0x7c00
+; GFX7SELDAG-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7SELDAG-NEXT:    v_cmp_eq_u32_e32 vcc, s4, v0
+; GFX7SELDAG-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX7SELDAG-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX7GLISEL-LABEL: not_isfinite_or_nan_f:
+; GFX7GLISEL:       ; %bb.0: ; %entry
+; GFX7GLISEL-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX7GLISEL-NEXT:    v_and_b32_e32 v0, 0x7fff, v0
+; GFX7GLISEL-NEXT:    v_bfe_u32 v0, v0, 0, 16
+; GFX7GLISEL-NEXT:    v_mov_b32_e32 v1, 0x7c00
+; GFX7GLISEL-NEXT:    v_cmp_eq_u32_e32 vcc, v0, v1
+; GFX7GLISEL-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX7GLISEL-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX8CHECK-LABEL: not_isfinite_or_nan_f:
+; GFX8CHECK:       ; %bb.0: ; %entry
+; GFX8CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX8CHECK-NEXT:    v_mov_b32_e32 v1, 0x204
+; GFX8CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX8CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX8CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX9CHECK-LABEL: not_isfinite_or_nan_f:
+; GFX9CHECK:       ; %bb.0: ; %entry
+; GFX9CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9CHECK-NEXT:    v_mov_b32_e32 v1, 0x204
+; GFX9CHECK-NEXT:    v_cmp_class_f16_e32 vcc, v0, v1
+; GFX9CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, vcc
+; GFX9CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX10CHECK-LABEL: not_isfinite_or_nan_f:
+; GFX10CHECK:       ; %bb.0: ; %entry
+; GFX10CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX10CHECK-NEXT:    v_cmp_class_f16_e64 s4, v0, 0x204
+; GFX10CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s4
+; GFX10CHECK-NEXT:    s_setpc_b64 s[30:31]
+;
+; GFX11CHECK-LABEL: not_isfinite_or_nan_f:
+; GFX11CHECK:       ; %bb.0: ; %entry
+; GFX11CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
+; GFX11CHECK-NEXT:    v_cmp_class_f16_e64 s0, v0, 0x204
+; GFX11CHECK-NEXT:    v_cndmask_b32_e64 v0, 0, 1, s0
+; GFX11CHECK-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f16(half %x, i32 516)  ; ~(0x1f8|0x3) = "~(finite|nan)"
+  ret i1 %0
+}
+
 declare i1 @llvm.is.fpclass.f16(half, i32)
 declare <2 x i1> @llvm.is.fpclass.v2f16(<2 x half>, i32)
 declare <3 x i1> @llvm.is.fpclass.v3f16(<3 x half>, i32)
 declare <4 x i1> @llvm.is.fpclass.v4f16(<4 x half>, i32)
+
+; Assume DAZ
+attributes #0 = { "denormal-fp-math"="ieee,preserve-sign" }
+
+; Maybe daz
+attributes #1 = { "denormal-fp-math"="ieee,dynamic" }

diff  --git a/llvm/test/CodeGen/X86/is_fpclass.ll b/llvm/test/CodeGen/X86/is_fpclass.ll
index edeadd01893cb..18a5b2737bbe8 100644
--- a/llvm/test/CodeGen/X86/is_fpclass.ll
+++ b/llvm/test/CodeGen/X86/is_fpclass.ll
@@ -71,6 +71,33 @@ entry:
   ret i1 %0
 }
 
+define i1 @not_issignaling_f(float %x) {
+; CHECK-32-LABEL: not_issignaling_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    cmpl $2143289344, %eax # imm = 0x7FC00000
+; CHECK-32-NEXT:    setge %cl
+; CHECK-32-NEXT:    cmpl $2139095041, %eax # imm = 0x7F800001
+; CHECK-32-NEXT:    setl %al
+; CHECK-32-NEXT:    orb %cl, %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_issignaling_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    cmpl $2143289344, %eax # imm = 0x7FC00000
+; CHECK-64-NEXT:    setge %cl
+; CHECK-64-NEXT:    cmpl $2139095041, %eax # imm = 0x7F800001
+; CHECK-64-NEXT:    setl %al
+; CHECK-64-NEXT:    orb %cl, %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1022)  ; ~"snan"
+  ret i1 %0
+}
+
 define i1 @isquiet_f(float %x) {
 ; CHECK-32-LABEL: isquiet_f:
 ; CHECK-32:       # %bb.0: # %entry
@@ -92,6 +119,27 @@ entry:
   ret i1 %0
 }
 
+define i1 @not_isquiet_f(float %x) {
+; CHECK-32-LABEL: not_isquiet_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    cmpl $2143289344, %eax # imm = 0x7FC00000
+; CHECK-32-NEXT:    setl %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_isquiet_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    cmpl $2143289344, %eax # imm = 0x7FC00000
+; CHECK-64-NEXT:    setl %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1021)  ; ~"qnan"
+  ret i1 %0
+}
+
 define i1 @isinf_f(float %x) {
 ; CHECK-32-LABEL: isinf_f:
 ; CHECK-32:       # %bb.0: # %entry
@@ -113,6 +161,27 @@ entry:
   ret i1 %0
 }
 
+define i1 @not_isinf_f(float %x) {
+; CHECK-32-LABEL: not_isinf_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-32-NEXT:    setne %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_isinf_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-64-NEXT:    setne %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 507)  ; ~0x204 = "~inf"
+  ret i1 %0
+}
+
 define i1 @is_plus_inf_f(float %x) {
 ; CHECK-32-LABEL: is_plus_inf_f:
 ; CHECK-32:       # %bb.0: # %entry
@@ -149,6 +218,24 @@ entry:
   ret i1 %0
 }
 
+define i1 @not_is_minus_inf_f(float %x) {
+; CHECK-32-LABEL: not_is_minus_inf_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    cmpl $-8388608, {{[0-9]+}}(%esp) # imm = 0xFF800000
+; CHECK-32-NEXT:    setne %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_is_minus_inf_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    cmpl $-8388608, %eax # imm = 0xFF800000
+; CHECK-64-NEXT:    setne %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1019)  ; ~"-inf"
+  ret i1 %0
+}
+
 define i1 @isfinite_f(float %x) {
 ; CHECK-32-LABEL: isfinite_f:
 ; CHECK-32:       # %bb.0: # %entry
@@ -170,6 +257,27 @@ entry:
   ret i1 %0
 }
 
+define i1 @not_isfinite_f(float %x) {
+; CHECK-32-LABEL: not_isfinite_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-32-NEXT:    setge %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_isfinite_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-64-NEXT:    setge %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 519)  ; ~0x1f8 = "~finite"
+  ret i1 %0
+}
+
 define i1 @is_plus_finite_f(float %x) {
 ; CHECK-32-LABEL: is_plus_finite_f:
 ; CHECK-32:       # %bb.0: # %entry
@@ -188,6 +296,24 @@ entry:
   ret i1 %0
 }
 
+define i1 @not_is_plus_finite_f(float %x) {
+; CHECK-32-LABEL: not_is_plus_finite_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    cmpl $2139095040, {{[0-9]+}}(%esp) # imm = 0x7F800000
+; CHECK-32-NEXT:    setae %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_is_plus_finite_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-64-NEXT:    setae %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 575)  ; ~0x1c0 = ~"+finite"
+  ret i1 %0
+}
+
 define i1 @is_minus_finite_f(float %x) {
 ; CHECK-32-LABEL: is_minus_finite_f:
 ; CHECK-32:       # %bb.0: # %entry
@@ -215,7 +341,34 @@ entry:
   ret i1 %0
 }
 
-define i1 @isnormal_f(float %x) {
+define i1 @not_is_minus_finite_f(float %x) {
+; CHECK-32-LABEL: not_is_minus_finite_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    testl %eax, %eax
+; CHECK-32-NEXT:    setns %cl
+; CHECK-32-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-32-NEXT:    setge %al
+; CHECK-32-NEXT:    orb %cl, %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_is_minus_finite_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    testl %eax, %eax
+; CHECK-64-NEXT:    setns %cl
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-64-NEXT:    setge %al
+; CHECK-64-NEXT:    orb %cl, %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 967)  ; ~0x38 = ~"-finite"
+  ret i1 %0
+}
+
+define i1 @isnormal_f(float %x) #1 {
 ; CHECK-32-LABEL: isnormal_f:
 ; CHECK-32:       # %bb.0: # %entry
 ; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
@@ -238,6 +391,29 @@ entry:
   ret i1 %0
 }
 
+define i1 @not_isnormal_f(float %x) #1 {
+; CHECK-32-LABEL: not_isnormal_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    addl $-8388608, %eax # imm = 0xFF800000
+; CHECK-32-NEXT:    cmpl $2130706432, %eax # imm = 0x7F000000
+; CHECK-32-NEXT:    setae %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_isnormal_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    addl $-8388608, %eax # imm = 0xFF800000
+; CHECK-64-NEXT:    cmpl $2130706432, %eax # imm = 0x7F000000
+; CHECK-64-NEXT:    setae %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 759)  ; ~0x108 = "~normal"
+  ret i1 %0
+}
+
 define i1 @is_plus_normal_f(float %x) {
 ; CHECK-32-LABEL: is_plus_normal_f:
 ; CHECK-32:       # %bb.0: # %entry
@@ -336,6 +512,75 @@ entry:
   ret i1 %0
 }
 
+define i1 @not_issubnormal_f(float %x) {
+; CHECK-32-LABEL: not_issubnormal_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    decl %eax
+; CHECK-32-NEXT:    cmpl $8388607, %eax # imm = 0x7FFFFF
+; CHECK-32-NEXT:    setae %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_issubnormal_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    decl %eax
+; CHECK-64-NEXT:    cmpl $8388607, %eax # imm = 0x7FFFFF
+; CHECK-64-NEXT:    setae %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 879)  ; ~0x90 = "~subnormal"
+  ret i1 %0
+}
+
+define i1 @not_issubnormal_f_daz(float %x) #0 {
+; CHECK-32-LABEL: not_issubnormal_f_daz:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    decl %eax
+; CHECK-32-NEXT:    cmpl $8388607, %eax # imm = 0x7FFFFF
+; CHECK-32-NEXT:    setae %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_issubnormal_f_daz:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    decl %eax
+; CHECK-64-NEXT:    cmpl $8388607, %eax # imm = 0x7FFFFF
+; CHECK-64-NEXT:    setae %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 879)  ; ~0x90 = "~subnormal"
+  ret i1 %0
+}
+
+define i1 @not_issubnormal_f_maybe_daz(float %x) #1 {
+; CHECK-32-LABEL: not_issubnormal_f_maybe_daz:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    decl %eax
+; CHECK-32-NEXT:    cmpl $8388607, %eax # imm = 0x7FFFFF
+; CHECK-32-NEXT:    setae %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_issubnormal_f_maybe_daz:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    decl %eax
+; CHECK-64-NEXT:    cmpl $8388607, %eax # imm = 0x7FFFFF
+; CHECK-64-NEXT:    setae %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 879)  ; ~0x90 = "~subnormal"
+  ret i1 %0
+}
+
 define i1 @is_plus_subnormal_f(float %x) {
 ; CHECK-32-LABEL: is_plus_subnormal_f:
 ; CHECK-32:       # %bb.0: # %entry
@@ -357,6 +602,27 @@ entry:
   ret i1 %0
 }
 
+define i1 @not_is_plus_subnormal_f(float %x) {
+; CHECK-32-LABEL: not_is_plus_subnormal_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    decl %eax
+; CHECK-32-NEXT:    cmpl $8388607, %eax # imm = 0x7FFFFF
+; CHECK-32-NEXT:    setae %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_is_plus_subnormal_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    decl %eax
+; CHECK-64-NEXT:    cmpl $8388607, %eax # imm = 0x7FFFFF
+; CHECK-64-NEXT:    setae %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 895)  ; ~0x80 = ~"+subnormal"
+  ret i1 %0
+}
+
 define i1 @is_minus_subnormal_f(float %x) {
 ; CHECK-32-LABEL: is_minus_subnormal_f:
 ; CHECK-32:       # %bb.0: # %entry
@@ -386,6 +652,35 @@ entry:
   ret i1 %0
 }
 
+define i1 @not_is_minus_subnormal_f(float %x) {
+; CHECK-32-LABEL: not_is_minus_subnormal_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    testl %eax, %eax
+; CHECK-32-NEXT:    setns %cl
+; CHECK-32-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    decl %eax
+; CHECK-32-NEXT:    cmpl $8388607, %eax # imm = 0x7FFFFF
+; CHECK-32-NEXT:    setae %al
+; CHECK-32-NEXT:    orb %cl, %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_is_minus_subnormal_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    testl %eax, %eax
+; CHECK-64-NEXT:    setns %cl
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    decl %eax
+; CHECK-64-NEXT:    cmpl $8388607, %eax # imm = 0x7FFFFF
+; CHECK-64-NEXT:    setae %al
+; CHECK-64-NEXT:    orb %cl, %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1007)  ; ~0x10 = ~"-subnormal"
+  ret i1 %0
+}
+
 define i1 @iszero_f(float %x) {
 ; CHECK-32-LABEL: iszero_f:
 ; CHECK-32:       # %bb.0: # %entry
@@ -449,38 +744,101 @@ entry:
   ret i1 %0
 }
 
-define i1 @issubnormal_or_zero_f(float %x) {
-; CHECK-32-LABEL: issubnormal_or_zero_f:
+define i1 @not_iszero_f(float %x) {
+; CHECK-32-LABEL: not_iszero_f:
 ; CHECK-32:       # %bb.0: # %entry
-; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
-; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
-; CHECK-32-NEXT:    sete %cl
-; CHECK-32-NEXT:    decl %eax
-; CHECK-32-NEXT:    cmpl $8388607, %eax # imm = 0x7FFFFF
-; CHECK-32-NEXT:    setb %al
+; CHECK-32-NEXT:    flds {{[0-9]+}}(%esp)
+; CHECK-32-NEXT:    fldz
+; CHECK-32-NEXT:    fucompp
+; CHECK-32-NEXT:    fnstsw %ax
+; CHECK-32-NEXT:    # kill: def $ah killed $ah killed $ax
+; CHECK-32-NEXT:    sahf
+; CHECK-32-NEXT:    setp %cl
+; CHECK-32-NEXT:    setne %al
 ; CHECK-32-NEXT:    orb %cl, %al
 ; CHECK-32-NEXT:    retl
 ;
-; CHECK-64-LABEL: issubnormal_or_zero_f:
+; CHECK-64-LABEL: not_iszero_f:
 ; CHECK-64:       # %bb.0: # %entry
-; CHECK-64-NEXT:    movd %xmm0, %eax
-; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
-; CHECK-64-NEXT:    sete %cl
-; CHECK-64-NEXT:    decl %eax
-; CHECK-64-NEXT:    cmpl $8388607, %eax # imm = 0x7FFFFF
-; CHECK-64-NEXT:    setb %al
-; CHECK-64-NEXT:    orb %cl, %al
+; CHECK-64-NEXT:    xorps %xmm1, %xmm1
+; CHECK-64-NEXT:    cmpneqss %xmm0, %xmm1
+; CHECK-64-NEXT:    movd %xmm1, %eax
+; CHECK-64-NEXT:    andl $1, %eax
+; CHECK-64-NEXT:    # kill: def $al killed $al killed $eax
 ; CHECK-64-NEXT:    retq
 entry:
-  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 240)  ; 0xf0 = "subnormal|zero"
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 927)  ; ~0x60 = "~zero"
   ret i1 %0
 }
 
-define i1 @issubnormal_or_zero_f_daz(float %x) #0 {
-; CHECK-32-LABEL: issubnormal_or_zero_f_daz:
+define i1 @not_iszero_f_daz(float %x) #0 {
+; CHECK-32-LABEL: not_iszero_f_daz:
 ; CHECK-32:       # %bb.0: # %entry
-; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
-; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    testl $2147483647, {{[0-9]+}}(%esp) # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    setne %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_iszero_f_daz:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    testl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    setne %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 927)  ; ~0x60 = "~zero"
+  ret i1 %0
+}
+
+define i1 @not_iszero_f_maybe_daz(float %x) #1 {
+; CHECK-32-LABEL: not_iszero_f_maybe_daz:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    testl $2147483647, {{[0-9]+}}(%esp) # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    setne %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_iszero_f_maybe_daz:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    testl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    setne %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 927)  ; ~0x60 = "~zero"
+  ret i1 %0
+}
+
+define i1 @issubnormal_or_zero_f(float %x) {
+; CHECK-32-LABEL: issubnormal_or_zero_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    sete %cl
+; CHECK-32-NEXT:    decl %eax
+; CHECK-32-NEXT:    cmpl $8388607, %eax # imm = 0x7FFFFF
+; CHECK-32-NEXT:    setb %al
+; CHECK-32-NEXT:    orb %cl, %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: issubnormal_or_zero_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    sete %cl
+; CHECK-64-NEXT:    decl %eax
+; CHECK-64-NEXT:    cmpl $8388607, %eax # imm = 0x7FFFFF
+; CHECK-64-NEXT:    setb %al
+; CHECK-64-NEXT:    orb %cl, %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 240)  ; 0xf0 = "subnormal|zero"
+  ret i1 %0
+}
+
+define i1 @issubnormal_or_zero_f_daz(float %x) #0 {
+; CHECK-32-LABEL: issubnormal_or_zero_f_daz:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
 ; CHECK-32-NEXT:    sete %cl
 ; CHECK-32-NEXT:    decl %eax
 ; CHECK-32-NEXT:    cmpl $8388607, %eax # imm = 0x7FFFFF
@@ -530,6 +888,93 @@ entry:
   ret i1 %0
 }
 
+define i1 @not_issubnormal_or_zero_f(float %x) {
+; CHECK-32-LABEL: not_issubnormal_or_zero_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-32-NEXT:    setge %cl
+; CHECK-32-NEXT:    addl $-8388608, %eax # imm = 0xFF800000
+; CHECK-32-NEXT:    cmpl $2130706432, %eax # imm = 0x7F000000
+; CHECK-32-NEXT:    setb %al
+; CHECK-32-NEXT:    orb %cl, %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_issubnormal_or_zero_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-64-NEXT:    setge %cl
+; CHECK-64-NEXT:    addl $-8388608, %eax # imm = 0xFF800000
+; CHECK-64-NEXT:    cmpl $2130706432, %eax # imm = 0x7F000000
+; CHECK-64-NEXT:    setb %al
+; CHECK-64-NEXT:    orb %cl, %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 783)  ; ~0xf0 = "~(subnormal|zero)"
+  ret i1 %0
+}
+
+define i1 @not_issubnormal_or_zero_f_daz(float %x) #0 {
+; CHECK-32-LABEL: not_issubnormal_or_zero_f_daz:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-32-NEXT:    setge %cl
+; CHECK-32-NEXT:    addl $-8388608, %eax # imm = 0xFF800000
+; CHECK-32-NEXT:    cmpl $2130706432, %eax # imm = 0x7F000000
+; CHECK-32-NEXT:    setb %al
+; CHECK-32-NEXT:    orb %cl, %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_issubnormal_or_zero_f_daz:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-64-NEXT:    setge %cl
+; CHECK-64-NEXT:    addl $-8388608, %eax # imm = 0xFF800000
+; CHECK-64-NEXT:    cmpl $2130706432, %eax # imm = 0x7F000000
+; CHECK-64-NEXT:    setb %al
+; CHECK-64-NEXT:    orb %cl, %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 783)  ; ~0xf0 = "~(subnormal|zero)"
+  ret i1 %0
+}
+
+define i1 @not_issubnormal_or_zero_f_maybe_daz(float %x) #1 {
+; CHECK-32-LABEL: not_issubnormal_or_zero_f_maybe_daz:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-32-NEXT:    setge %cl
+; CHECK-32-NEXT:    addl $-8388608, %eax # imm = 0xFF800000
+; CHECK-32-NEXT:    cmpl $2130706432, %eax # imm = 0x7F000000
+; CHECK-32-NEXT:    setb %al
+; CHECK-32-NEXT:    orb %cl, %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_issubnormal_or_zero_f_maybe_daz:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-64-NEXT:    setge %cl
+; CHECK-64-NEXT:    addl $-8388608, %eax # imm = 0xFF800000
+; CHECK-64-NEXT:    cmpl $2130706432, %eax # imm = 0x7F000000
+; CHECK-64-NEXT:    setb %al
+; CHECK-64-NEXT:    orb %cl, %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 783)  ; ~0xf0 = "~(subnormal|zero)"
+  ret i1 %0
+}
+
 define i1 @is_plus_zero_f(float %x) {
 ; CHECK-32-LABEL: is_plus_zero_f:
 ; CHECK-32:       # %bb.0: # %entry
@@ -548,6 +993,24 @@ entry:
   ret i1 %0
 }
 
+define i1 @not_is_plus_zero_f(float %x) {
+; CHECK-32-LABEL: not_is_plus_zero_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    cmpl $0, {{[0-9]+}}(%esp)
+; CHECK-32-NEXT:    setne %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_is_plus_zero_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    testl %eax, %eax
+; CHECK-64-NEXT:    setne %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 959)  ; ~0x40 = ~"+zero"
+  ret i1 %0
+}
+
 define i1 @is_minus_zero_f(float %x) {
 ; CHECK-32-LABEL: is_minus_zero_f:
 ; CHECK-32:       # %bb.0: # %entry
@@ -566,7 +1029,23 @@ entry:
   ret i1 %0
 }
 
-
+define i1 @not_is_minus_zero_f(float %x) {
+; CHECK-32-LABEL: not_is_minus_zero_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    cmpl $-2147483648, {{[0-9]+}}(%esp) # imm = 0x80000000
+; CHECK-32-NEXT:    setne %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_is_minus_zero_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    cmpl $-2147483648, %eax # imm = 0x80000000
+; CHECK-64-NEXT:    setne %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 991)  ; ~0x20 = ~"-zero"
+  ret i1 %0
+}
 
 define i1 @isnan_f_strictfp(float %x) strictfp {
 ; CHECK-32-LABEL: isnan_f_strictfp:
@@ -589,6 +1068,27 @@ entry:
   ret i1 %0
 }
 
+define i1 @not_isnan_f_strictfp(float %x) strictfp {
+; CHECK-32-LABEL: not_isnan_f_strictfp:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    cmpl $2139095041, %eax # imm = 0x7F800001
+; CHECK-32-NEXT:    setl %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_isnan_f_strictfp:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    cmpl $2139095041, %eax # imm = 0x7F800001
+; CHECK-64-NEXT:    setl %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 1020)  ; ~"nan"
+  ret i1 %0
+}
+
 define i1 @isfinite_f_strictfp(float %x) strictfp {
 ; CHECK-32-LABEL: isfinite_f_strictfp:
 ; CHECK-32:       # %bb.0: # %entry
@@ -610,6 +1110,27 @@ entry:
   ret i1 %0
 }
 
+define i1 @not_isfinite_f_strictfp(float %x) strictfp {
+; CHECK-32-LABEL: not_isfinite_f_strictfp:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-32-NEXT:    setge %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_isfinite_f_strictfp:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-64-NEXT:    setge %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 519)  ; ~0x1f8 = ~"finite"
+  ret i1 %0
+}
+
 define i1 @iszero_f_strictfp(float %x) strictfp {
 ; CHECK-32-LABEL: iszero_f_strictfp:
 ; CHECK-32:       # %bb.0: # %entry
@@ -628,6 +1149,23 @@ entry:
   ret i1 %0
 }
 
+define i1 @not_iszero_f_strictfp(float %x) strictfp {
+; CHECK-32-LABEL: not_iszero_f_strictfp:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    testl $2147483647, {{[0-9]+}}(%esp) # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    setne %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_iszero_f_strictfp:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    testl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    setne %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 927)  ; ~0x60 = ~"zero"
+  ret i1 %0
+}
 
 define i1 @isnan_d(double %x) {
 ; CHECK-32-LABEL: isnan_d:
@@ -1129,6 +1667,433 @@ entry:
 }
 
 
+define i1 @iszero_or_nan_f(float %x) {
+; CHECK-32-LABEL: iszero_or_nan_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    cmpl $2139095041, %eax # imm = 0x7F800001
+; CHECK-32-NEXT:    setge %cl
+; CHECK-32-NEXT:    testl %eax, %eax
+; CHECK-32-NEXT:    sete %al
+; CHECK-32-NEXT:    orb %cl, %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: iszero_or_nan_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    cmpl $2139095041, %eax # imm = 0x7F800001
+; CHECK-64-NEXT:    setge %cl
+; CHECK-64-NEXT:    testl %eax, %eax
+; CHECK-64-NEXT:    sete %al
+; CHECK-64-NEXT:    orb %cl, %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 99)  ; 0x60|0x3 = "zero|nan"
+  ret i1 %0
+}
+
+define i1 @iszero_or_nan_f_daz(float %x) #0 {
+; CHECK-32-LABEL: iszero_or_nan_f_daz:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    cmpl $2139095041, %eax # imm = 0x7F800001
+; CHECK-32-NEXT:    setge %cl
+; CHECK-32-NEXT:    testl %eax, %eax
+; CHECK-32-NEXT:    sete %al
+; CHECK-32-NEXT:    orb %cl, %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: iszero_or_nan_f_daz:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    cmpl $2139095041, %eax # imm = 0x7F800001
+; CHECK-64-NEXT:    setge %cl
+; CHECK-64-NEXT:    testl %eax, %eax
+; CHECK-64-NEXT:    sete %al
+; CHECK-64-NEXT:    orb %cl, %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 99)  ; 0x60|0x3 = "zero|nan"
+  ret i1 %0
+}
+
+define i1 @iszero_or_nan_f_maybe_daz(float %x) #1 {
+; CHECK-32-LABEL: iszero_or_nan_f_maybe_daz:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    cmpl $2139095041, %eax # imm = 0x7F800001
+; CHECK-32-NEXT:    setge %cl
+; CHECK-32-NEXT:    testl %eax, %eax
+; CHECK-32-NEXT:    sete %al
+; CHECK-32-NEXT:    orb %cl, %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: iszero_or_nan_f_maybe_daz:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    cmpl $2139095041, %eax # imm = 0x7F800001
+; CHECK-64-NEXT:    setge %cl
+; CHECK-64-NEXT:    testl %eax, %eax
+; CHECK-64-NEXT:    sete %al
+; CHECK-64-NEXT:    orb %cl, %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 99)  ; 0x60|0x3 = "zero|nan"
+  ret i1 %0
+}
+
+define i1 @not_iszero_or_nan_f(float %x) {
+; CHECK-32-LABEL: not_iszero_or_nan_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-32-NEXT:    sete %cl
+; CHECK-32-NEXT:    leal -1(%eax), %edx
+; CHECK-32-NEXT:    cmpl $8388607, %edx # imm = 0x7FFFFF
+; CHECK-32-NEXT:    setb %dl
+; CHECK-32-NEXT:    orb %cl, %dl
+; CHECK-32-NEXT:    addl $-8388608, %eax # imm = 0xFF800000
+; CHECK-32-NEXT:    cmpl $2130706432, %eax # imm = 0x7F000000
+; CHECK-32-NEXT:    setb %al
+; CHECK-32-NEXT:    orb %dl, %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_iszero_or_nan_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-64-NEXT:    sete %cl
+; CHECK-64-NEXT:    leal -1(%rax), %edx
+; CHECK-64-NEXT:    cmpl $8388607, %edx # imm = 0x7FFFFF
+; CHECK-64-NEXT:    setb %dl
+; CHECK-64-NEXT:    orb %cl, %dl
+; CHECK-64-NEXT:    addl $-8388608, %eax # imm = 0xFF800000
+; CHECK-64-NEXT:    cmpl $2130706432, %eax # imm = 0x7F000000
+; CHECK-64-NEXT:    setb %al
+; CHECK-64-NEXT:    orb %dl, %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 924)  ; ~0x60 = "~(zero|nan)"
+  ret i1 %0
+}
+
+define i1 @not_iszero_or_nan_f_daz(float %x) #0 {
+; CHECK-32-LABEL: not_iszero_or_nan_f_daz:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-32-NEXT:    sete %cl
+; CHECK-32-NEXT:    leal -1(%eax), %edx
+; CHECK-32-NEXT:    cmpl $8388607, %edx # imm = 0x7FFFFF
+; CHECK-32-NEXT:    setb %dl
+; CHECK-32-NEXT:    orb %cl, %dl
+; CHECK-32-NEXT:    addl $-8388608, %eax # imm = 0xFF800000
+; CHECK-32-NEXT:    cmpl $2130706432, %eax # imm = 0x7F000000
+; CHECK-32-NEXT:    setb %al
+; CHECK-32-NEXT:    orb %dl, %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_iszero_or_nan_f_daz:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-64-NEXT:    sete %cl
+; CHECK-64-NEXT:    leal -1(%rax), %edx
+; CHECK-64-NEXT:    cmpl $8388607, %edx # imm = 0x7FFFFF
+; CHECK-64-NEXT:    setb %dl
+; CHECK-64-NEXT:    orb %cl, %dl
+; CHECK-64-NEXT:    addl $-8388608, %eax # imm = 0xFF800000
+; CHECK-64-NEXT:    cmpl $2130706432, %eax # imm = 0x7F000000
+; CHECK-64-NEXT:    setb %al
+; CHECK-64-NEXT:    orb %dl, %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 924)  ; ~(0x60|0x3) = "~(zero|nan)"
+  ret i1 %0
+}
+
+define i1 @not_iszero_or_nan_f_maybe_daz(float %x) #1 {
+; CHECK-32-LABEL: not_iszero_or_nan_f_maybe_daz:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-32-NEXT:    sete %cl
+; CHECK-32-NEXT:    leal -1(%eax), %edx
+; CHECK-32-NEXT:    cmpl $8388607, %edx # imm = 0x7FFFFF
+; CHECK-32-NEXT:    setb %dl
+; CHECK-32-NEXT:    orb %cl, %dl
+; CHECK-32-NEXT:    addl $-8388608, %eax # imm = 0xFF800000
+; CHECK-32-NEXT:    cmpl $2130706432, %eax # imm = 0x7F000000
+; CHECK-32-NEXT:    setb %al
+; CHECK-32-NEXT:    orb %dl, %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_iszero_or_nan_f_maybe_daz:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-64-NEXT:    sete %cl
+; CHECK-64-NEXT:    leal -1(%rax), %edx
+; CHECK-64-NEXT:    cmpl $8388607, %edx # imm = 0x7FFFFF
+; CHECK-64-NEXT:    setb %dl
+; CHECK-64-NEXT:    orb %cl, %dl
+; CHECK-64-NEXT:    addl $-8388608, %eax # imm = 0xFF800000
+; CHECK-64-NEXT:    cmpl $2130706432, %eax # imm = 0x7F000000
+; CHECK-64-NEXT:    setb %al
+; CHECK-64-NEXT:    orb %dl, %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 924)  ; ~(0x60|0x3) = "~(zero|nan)"
+  ret i1 %0
+}
+
+define i1 @iszero_or_qnan_f(float %x) {
+; CHECK-32-LABEL: iszero_or_qnan_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    cmpl $2143289344, %eax # imm = 0x7FC00000
+; CHECK-32-NEXT:    setge %cl
+; CHECK-32-NEXT:    testl %eax, %eax
+; CHECK-32-NEXT:    sete %al
+; CHECK-32-NEXT:    orb %cl, %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: iszero_or_qnan_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    cmpl $2143289344, %eax # imm = 0x7FC00000
+; CHECK-64-NEXT:    setge %cl
+; CHECK-64-NEXT:    testl %eax, %eax
+; CHECK-64-NEXT:    sete %al
+; CHECK-64-NEXT:    orb %cl, %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 98)  ; 0x60|0x2 = "zero|qnan"
+  ret i1 %0
+}
+
+define i1 @iszero_or_snan_f(float %x) {
+; CHECK-32-LABEL: iszero_or_snan_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    cmpl $2143289344, %eax # imm = 0x7FC00000
+; CHECK-32-NEXT:    setl %cl
+; CHECK-32-NEXT:    cmpl $2139095041, %eax # imm = 0x7F800001
+; CHECK-32-NEXT:    setge %dl
+; CHECK-32-NEXT:    andb %cl, %dl
+; CHECK-32-NEXT:    testl %eax, %eax
+; CHECK-32-NEXT:    sete %al
+; CHECK-32-NEXT:    orb %dl, %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: iszero_or_snan_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    cmpl $2143289344, %eax # imm = 0x7FC00000
+; CHECK-64-NEXT:    setl %cl
+; CHECK-64-NEXT:    cmpl $2139095041, %eax # imm = 0x7F800001
+; CHECK-64-NEXT:    setge %dl
+; CHECK-64-NEXT:    andb %cl, %dl
+; CHECK-64-NEXT:    testl %eax, %eax
+; CHECK-64-NEXT:    sete %al
+; CHECK-64-NEXT:    orb %dl, %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 97)  ; 0x60|0x1 = "zero|snan"
+  ret i1 %0
+}
+
+define i1 @not_iszero_or_qnan_f(float %x) {
+; CHECK-32-LABEL: not_iszero_or_qnan_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    cmpl $2143289344, %eax # imm = 0x7FC00000
+; CHECK-32-NEXT:    setl %cl
+; CHECK-32-NEXT:    cmpl $2139095041, %eax # imm = 0x7F800001
+; CHECK-32-NEXT:    setge %dl
+; CHECK-32-NEXT:    andb %cl, %dl
+; CHECK-32-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-32-NEXT:    sete %cl
+; CHECK-32-NEXT:    orb %dl, %cl
+; CHECK-32-NEXT:    leal -1(%eax), %edx
+; CHECK-32-NEXT:    cmpl $8388607, %edx # imm = 0x7FFFFF
+; CHECK-32-NEXT:    setb %dl
+; CHECK-32-NEXT:    addl $-8388608, %eax # imm = 0xFF800000
+; CHECK-32-NEXT:    cmpl $2130706432, %eax # imm = 0x7F000000
+; CHECK-32-NEXT:    setb %al
+; CHECK-32-NEXT:    orb %dl, %al
+; CHECK-32-NEXT:    orb %cl, %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_iszero_or_qnan_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    cmpl $2143289344, %eax # imm = 0x7FC00000
+; CHECK-64-NEXT:    setl %cl
+; CHECK-64-NEXT:    cmpl $2139095041, %eax # imm = 0x7F800001
+; CHECK-64-NEXT:    setge %dl
+; CHECK-64-NEXT:    andb %cl, %dl
+; CHECK-64-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-64-NEXT:    sete %cl
+; CHECK-64-NEXT:    orb %dl, %cl
+; CHECK-64-NEXT:    leal -1(%rax), %edx
+; CHECK-64-NEXT:    cmpl $8388607, %edx # imm = 0x7FFFFF
+; CHECK-64-NEXT:    setb %dl
+; CHECK-64-NEXT:    addl $-8388608, %eax # imm = 0xFF800000
+; CHECK-64-NEXT:    cmpl $2130706432, %eax # imm = 0x7F000000
+; CHECK-64-NEXT:    setb %al
+; CHECK-64-NEXT:    orb %dl, %al
+; CHECK-64-NEXT:    orb %cl, %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 925)  ; ~(0x60|0x2) = "~(zero|qnan)"
+  ret i1 %0
+}
+
+define i1 @not_iszero_or_snan_f(float %x) {
+; CHECK-32-LABEL: not_iszero_or_snan_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    cmpl $2143289344, %eax # imm = 0x7FC00000
+; CHECK-32-NEXT:    setge %cl
+; CHECK-32-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-32-NEXT:    sete %dl
+; CHECK-32-NEXT:    orb %cl, %dl
+; CHECK-32-NEXT:    leal -1(%eax), %ecx
+; CHECK-32-NEXT:    cmpl $8388607, %ecx # imm = 0x7FFFFF
+; CHECK-32-NEXT:    setb %cl
+; CHECK-32-NEXT:    orb %dl, %cl
+; CHECK-32-NEXT:    addl $-8388608, %eax # imm = 0xFF800000
+; CHECK-32-NEXT:    cmpl $2130706432, %eax # imm = 0x7F000000
+; CHECK-32-NEXT:    setb %al
+; CHECK-32-NEXT:    orb %cl, %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_iszero_or_snan_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    cmpl $2143289344, %eax # imm = 0x7FC00000
+; CHECK-64-NEXT:    setge %cl
+; CHECK-64-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-64-NEXT:    sete %dl
+; CHECK-64-NEXT:    orb %cl, %dl
+; CHECK-64-NEXT:    leal -1(%rax), %ecx
+; CHECK-64-NEXT:    cmpl $8388607, %ecx # imm = 0x7FFFFF
+; CHECK-64-NEXT:    setb %cl
+; CHECK-64-NEXT:    orb %dl, %cl
+; CHECK-64-NEXT:    addl $-8388608, %eax # imm = 0xFF800000
+; CHECK-64-NEXT:    cmpl $2130706432, %eax # imm = 0x7F000000
+; CHECK-64-NEXT:    setb %al
+; CHECK-64-NEXT:    orb %cl, %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 926)  ; ~(0x60|0x1) = "~(zero|snan)"
+  ret i1 %0
+}
+
+define i1 @isinf_or_nan_f(float %x) {
+; CHECK-32-LABEL: isinf_or_nan_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-32-NEXT:    setge %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: isinf_or_nan_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-64-NEXT:    setge %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 519)  ; 0x204|0x3 = "inf|nan"
+  ret i1 %0
+}
+
+define i1 @not_isinf_or_nan_f(float %x) {
+; CHECK-32-LABEL: not_isinf_or_nan_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-32-NEXT:    setl %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_isinf_or_nan_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-64-NEXT:    setl %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 504)  ; ~(0x204|0x3) = "~(inf|nan)"
+  ret i1 %0
+}
+
+define i1 @isfinite_or_nan_f(float %x) {
+; CHECK-32-LABEL: isfinite_or_nan_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-32-NEXT:    setne %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: isfinite_or_nan_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-64-NEXT:    setne %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 507)  ; 0x1f8|0x3 = "finite|nan"
+  ret i1 %0
+}
+
+define i1 @not_isfinite_or_nan_f(float %x) {
+; CHECK-32-LABEL: not_isfinite_or_nan_f:
+; CHECK-32:       # %bb.0: # %entry
+; CHECK-32-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; CHECK-32-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-32-NEXT:    sete %al
+; CHECK-32-NEXT:    retl
+;
+; CHECK-64-LABEL: not_isfinite_or_nan_f:
+; CHECK-64:       # %bb.0: # %entry
+; CHECK-64-NEXT:    movd %xmm0, %eax
+; CHECK-64-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
+; CHECK-64-NEXT:    cmpl $2139095040, %eax # imm = 0x7F800000
+; CHECK-64-NEXT:    sete %al
+; CHECK-64-NEXT:    retq
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 516)  ; ~(0x1f8|0x3) = "~(finite|nan)"
+  ret i1 %0
+}
 
 declare i1 @llvm.is.fpclass.f32(float, i32)
 declare i1 @llvm.is.fpclass.f64(double, i32)


        


More information about the llvm-commits mailing list