> -----Original Message-----
> From: Wilco Dijkstra <wilco.dijks...@arm.com>
> Sent: Thursday, September 4, 2025 4:32 PM
> To: Kyrylo Tkachov <ktkac...@nvidia.com>; Alex Coplan
> <alex.cop...@arm.com>; Tamar Christina <tamar.christ...@arm.com>; Andrew
> Pinski <pins...@gmail.com>; Alice Carlotti <alice.carlo...@arm.com>
> Cc: GCC Patches <gcc-patches@gcc.gnu.org>
> Subject: [PATCH] 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.
>
> testsuite:
> PR middle-end/66462
> * gcc.target/aarch64/pr66462.c: Update test.
>
> ---
>
> diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
> index
> a63839a84382146c18acf3e0997470b068436654..68f781d68d58f9a723f1765
> 2a3cf952d4e74090a 100644
> --- a/gcc/config/aarch64/aarch64.md
> +++ b/gcc/config/aarch64/aarch64.md
> @@ -7722,6 +7722,22 @@ (define_expand "isfinite<mode>2"
> }
> )
>
> +(define_expand "isnan<mode>2"
> + [(match_operand:SI 0 "register_operand")
> + (match_operand:GPF 1 "register_operand")]
> + "TARGET_FLOAT && flag_signaling_nans"
> +{
> + rtx op = lowpart_subreg (<V_INT_EQUIV>mode, operands[1], <MODE>mode);
Similarly to the other patches needs force_lowpart_subreg due to operands[1]
might be
a paradoxical subreg where the integer conversion would return NULL if not
forced to
a register first.
OK with that change.
Thanks,
Tamar
> + 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
> 476d47c9b1928447da2042003135f21cbf795633..2bd734b3193c55e48bbcfb9
> 459bdf160b8b9443f 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;
> }