> -----Original Message-----
> From: Wilco Dijkstra <wilco.dijks...@arm.com>
> Sent: Wednesday, August 27, 2025 6:32 PM
> To: GCC Patches <gcc-patches@gcc.gnu.org>
> Cc: 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>
> Subject: [PATCH] AArch64: Add isfinite expander [PR 66462]
> 
> 
> Add an expander for isfinite using integer arithmetic.  This is
> typically faster and avoids generating spurious exceptions on
> signaling NaNs.  This fixes part of PR66462.
> 
> int isfinite1 (float x) { return __builtin_isfinite (x); }
> 
> Before:
>       fabs    s0, s0
>       mov     w0, 2139095039
>       fmov    s31, w0
>       fcmp    s0, s31
>       cset    w0, hi
>       eor     w0, w0, 1
>       ret
> 
> After:
>       fmov    w1, s0
>       mov     w0, -16777216
>       cmp     w0, w1, lsl 1
>       cset    w0, hi
>       ret
> 
> gcc:
>       PR middle-end/66462
>       * config/aarch64/aarch64.md (isfinite<mode>2): Add new expander.
> 
> testsuite:
>       PR middle-end/66462
>       * gcc.target/aarch64/pr66462.c: Add tests for isfinite.
> 
> ---
> 
> diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
> index
> d3bf85d1b67b6b777346fbd9a93f59cdc95f53ca..c11db4a51166f70dd3c9e0e0
> 9cca838498254fec 100644
> --- a/gcc/config/aarch64/aarch64.md
> +++ b/gcc/config/aarch64/aarch64.md
> @@ -7732,6 +7732,22 @@ (define_expand "isinf<mode>2"
>  }
>  )
> 
> +(define_expand "isfinite<mode>2"
> + [(match_operand:SI 0 "register_operand")
> +  (match_operand:GPF 1 "register_operand")]
> + "TARGET_FLOAT"
> +{
> +  rtx op = lowpart_subreg (<V_INT_EQUIV>mode, operands[1], <MODE>mode);

Also needs force_lowpart_subreg

> +  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 (LTU, SImode, cc_reg, const0_rtx);
> +  emit_insn (gen_aarch64_cstoresi (operands[0], cmp, cc_reg));
> +  DONE;
> +}
> +)
> +

Hmm this looks the same as isinf except for the operator in the compare.
Could we combine the two patterns?

Thanks,
Tamar

>  ;; -------------------------------------------------------------------
>  ;; Reload support
>  ;; -------------------------------------------------------------------
> diff --git a/gcc/testsuite/gcc.target/aarch64/pr66462.c
> b/gcc/testsuite/gcc.target/aarch64/pr66462.c
> index
> 9ebd48e922c95cfbccbe65987572b5c1c079bc8c..476d47c9b1928447da204200
> 3135f21cbf795633 100644
> --- a/gcc/testsuite/gcc.target/aarch64/pr66462.c
> +++ b/gcc/testsuite/gcc.target/aarch64/pr66462.c
> @@ -24,6 +24,26 @@ static void t_inf (double x, bool res)
>      __builtin_abort ();
>  }
> 
> +static void t_finf (float x, bool res)
> +{
> +  if (__builtin_isfinite (x) != res)
> +    __builtin_abort ();
> +  if (__builtin_isfinite (-x) != res)
> +    __builtin_abort ();
> +  if (fetestexcept (FE_INVALID))
> +    __builtin_abort ();
> +}
> +
> +static void t_fin (double x, bool res)
> +{
> +  if (__builtin_isfinite (x) != res)
> +    __builtin_abort ();
> +  if (__builtin_isfinite (-x) != res)
> +    __builtin_abort ();
> +  if (fetestexcept (FE_INVALID))
> +    __builtin_abort ();
> +}
> +
>  int
>  main ()
>  {
> @@ -41,5 +61,17 @@ main ()
>    t_inf (__builtin_nans (""), 0);
>    t_inf (__builtin_nan (""), 0);
> 
> +  t_finf (0.0f, 1);
> +  t_finf (1.0f, 1);
> +  t_finf (__builtin_inff (), 0);
> +  t_finf (__builtin_nansf (""), 0);
> +  t_finf (__builtin_nanf (""), 0);
> +
> +  t_fin (0.0, 1);
> +  t_fin (1.0, 1);
> +  t_fin (__builtin_inf (), 0);
> +  t_fin (__builtin_nans (""), 0);
> +  t_fin (__builtin_nan (""), 0);
> +
>    return 0;
>  }

Reply via email to