> -----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; > }