https://gcc.gnu.org/g:5b531aa5cc216b5ec4d740940b43ca7a7728cc90

commit r16-3909-g5b531aa5cc216b5ec4d740940b43ca7a7728cc90
Author: Wilco Dijkstra <[email protected]>
Date:   Thu Sep 4 14:31:16 2025 +0000

    AArch64: Add isnan expander [PR 66462]
    
    Add an expander for isnan using integer arithmetic.  Since isnan is
    just a compare, enable it only with -fsignaling-nans to avoid
    generating spurious exceptions.  This fixes part of PR66462.
    
    int isnan1 (float x) { return __builtin_isnan (x); }
    
    Before:
            fcmp    s0, s0
            cset    w0, vs
            ret
    
    After:
            fmov    w1, s0
            mov     w0, -16777216
            cmp     w0, w1, lsl 1
            cset    w0, cc
            ret
    
    gcc:
            PR middle-end/66462
            * config/aarch64/aarch64.md (isnan<mode>2): Add new expander.
    
    gcc/testsuite:
            PR middle-end/66462
            * gcc.target/aarch64/pr66462.c: Update test.

Diff:
---
 gcc/config/aarch64/aarch64.md              | 16 +++++++++++++++
 gcc/testsuite/gcc.target/aarch64/pr66462.c | 33 ++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+)

diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 6d30226c5978..ca612dac600a 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -7722,6 +7722,22 @@
 }
 )
 
+(define_expand "isnan<mode>2"
+ [(match_operand:SI 0 "register_operand")
+  (match_operand:GPF 1 "register_operand")]
+ "TARGET_FLOAT && flag_signaling_nans"
+{
+  rtx op = force_lowpart_subreg (<V_INT_EQUIV>mode, operands[1], <MODE>mode);
+  rtx tmp = gen_reg_rtx (<V_INT_EQUIV>mode);
+  emit_move_insn (tmp, GEN_INT (HOST_WIDE_INT_M1U << (<mantissa_bits> + 1)));
+  rtx cc_reg = gen_rtx_REG (CC_SWPmode, CC_REGNUM);
+  emit_insn (gen_cmp_swp_lsl_reg<v_int_equiv> (op, GEN_INT (1), tmp));
+  rtx cmp = gen_rtx_fmt_ee (GTU, SImode, cc_reg, const0_rtx);
+  emit_insn (gen_aarch64_cstoresi (operands[0], cmp, cc_reg));
+  DONE;
+}
+)
+
 ;; -------------------------------------------------------------------
 ;; Reload support
 ;; -------------------------------------------------------------------
diff --git a/gcc/testsuite/gcc.target/aarch64/pr66462.c 
b/gcc/testsuite/gcc.target/aarch64/pr66462.c
index 476d47c9b192..2bd734b3193c 100644
--- a/gcc/testsuite/gcc.target/aarch64/pr66462.c
+++ b/gcc/testsuite/gcc.target/aarch64/pr66462.c
@@ -44,6 +44,27 @@ static void t_fin (double x, bool res)
     __builtin_abort ();
 }
 
+static void t_nanf (float x, bool res)
+{
+  if (__builtin_isnan (x) != res)
+    __builtin_abort ();
+  if (__builtin_isnan (-x) != res)
+    __builtin_abort ();
+  if (fetestexcept (FE_INVALID))
+    __builtin_abort ();
+}
+
+static void t_nan (double x, bool res)
+{
+  if (__builtin_isnan (x) != res)
+    __builtin_abort ();
+  if (__builtin_isnan (-x) != res)
+    __builtin_abort ();
+  if (fetestexcept (FE_INVALID))
+    __builtin_abort ();
+}
+
+
 int
 main ()
 {
@@ -73,5 +94,17 @@ main ()
   t_fin (__builtin_nans (""), 0);
   t_fin (__builtin_nan (""), 0);
 
+  t_nanf (0.0f, 0);
+  t_nanf (1.0f, 0);
+  t_nanf (__builtin_inff (), 0);
+  t_nanf (__builtin_nansf (""), 1);
+  t_nanf (__builtin_nanf (""), 1);
+
+  t_nan (0.0, 0);
+  t_nan (1.0, 0);
+  t_nan (__builtin_inf (), 0);
+  t_nan (__builtin_nans (""), 1);
+  t_nan (__builtin_nan (""), 1);
+
   return 0;
 }

Reply via email to