> -----Original Message-----
> From: Wilco Dijkstra <[email protected]>
> Sent: Wednesday, August 27, 2025 6:04 PM
> To: Kyrylo Tkachov <[email protected]>
> Cc: GCC Patches <[email protected]>; Alex Coplan
> <[email protected]>; Tamar Christina <[email protected]>; Andrew
> Pinski <[email protected]>; Alice Carlotti <[email protected]>
> Subject: [PATCH v2] AArch64: Add isinf expander [PR 66462]
>
> v2: Add testcase
>
> Add an expander for isinf using integer arithmetic. This is
> typically faster and avoids generating spurious exceptions on
> signaling NaNs. This fixes part of PR66462.
>
> int isinf1 (float x) { return __builtin_isinf (x); }
>
> Before:
> fabs s0, s0
> mov w0, 2139095039
> fmov s31, w0
> fcmp s0, s31
> cset w0, le
> eor w0, w0, 1
> ret
>
> After:
> fmov w1, s0
> mov w0, -16777216
> cmp w0, w1, lsl 1
> cset w0, eq
> ret
>
> gcc:
> PR middle-end/66462
> * config/aarch64/aarch64.md (isinf<mode>2): Add new expander.
> * config/aarch64/iterators.md (mantissa_bits): Add new mode_attr.
>
> testsuite:
> PR middle-end/66462
> * gcc.target/aarch64/pr66462.c: Add new test.
>
> ---
>
> diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
> index
> dc2be815ede6829aa6f8b1f435754c3e98fa5c12..d3bf85d1b67b6b777346fbd9
> a93f59cdc95f53ca 100644
> --- a/gcc/config/aarch64/aarch64.md
> +++ b/gcc/config/aarch64/aarch64.md
> @@ -4524,7 +4524,7 @@ (define_insn "fcmpe<mode>"
> [(set_attr "type" "fcmp<stype>")]
> )
>
> -(define_insn "*cmp_swp_<shift>_reg<mode>"
> +(define_insn "cmp_swp_<shift>_reg<mode>"
> [(set (reg:CC_SWP CC_REGNUM)
> (compare:CC_SWP (ASHIFT:GPI
> (match_operand:GPI 0 "register_operand" "r")
> @@ -7716,6 +7716,22 @@ (define_expand "@xorsign<mode>3"
> }
> )
>
> +(define_expand "isinf<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);
I think you forgot the force_lowpart_subreg.
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 (EQ, SImode, cc_reg, const0_rtx);
> + emit_insn (gen_aarch64_cstoresi (operands[0], cmp, cc_reg));
> + DONE;
> +}
> +)
> +
> ;; -------------------------------------------------------------------
> ;; Reload support
> ;; -------------------------------------------------------------------
> diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
> index
> 8f8237edf6cb07f80beaa5dcf7a7330b06fed3c9..8fea19469baeaf12a3a8acfad11
> 589084c8c4301 100644
> --- a/gcc/config/aarch64/iterators.md
> +++ b/gcc/config/aarch64/iterators.md
> @@ -1334,6 +1334,8 @@ (define_mode_attr short_mask [(HI "65535") (QI
> "255")])
>
> (define_mode_attr half_mask [(HI "255") (SI "65535") (DI "4294967295")])
>
> +(define_mode_attr mantissa_bits [(SF "23") (DF "52")])
> +
> ;; For constraints used in scalar immediate vector moves
> (define_mode_attr hq [(HI "h") (QI "q")])
>
> diff --git a/gcc/testsuite/gcc.target/aarch64/pr66462.c
> b/gcc/testsuite/gcc.target/aarch64/pr66462.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..9ebd48e922c95cfbccbe65
> 987572b5c1c079bc8c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/pr66462.c
> @@ -0,0 +1,45 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2 -fsignaling-nans -fno-inline" } */
> +/* { dg-require-effective-target fenv_exceptions } */
> +
> +#include <fenv.h>
> +
> +static void t_inff (float x, bool res)
> +{
> + if (__builtin_isinff (x) != res)
> + __builtin_abort ();
> + if (__builtin_isinff (-x) != res)
> + __builtin_abort ();
> + if (fetestexcept (FE_INVALID))
> + __builtin_abort ();
> +}
> +
> +static void t_inf (double x, bool res)
> +{
> + if (__builtin_isinf (x) != res)
> + __builtin_abort ();
> + if (__builtin_isinf (-x) != res)
> + __builtin_abort ();
> + if (fetestexcept (FE_INVALID))
> + __builtin_abort ();
> +}
> +
> +int
> +main ()
> +{
> + feclearexcept (FE_INVALID);
> +
> + t_inff (0.0f, 0);
> + t_inff (1.0f, 0);
> + t_inff (__builtin_inff (), 1);
> + t_inff (__builtin_nansf (""), 0);
> + t_inff (__builtin_nanf (""), 0);
> +
> + t_inf (0.0, 0);
> + t_inf (1.0, 0);
> + t_inf (__builtin_inf (), 1);
> + t_inf (__builtin_nans (""), 0);
> + t_inf (__builtin_nan (""), 0);
> +
> + return 0;
> +}