> -----Original Message----- > From: Wilco Dijkstra <wilco.dijks...@arm.com> > Sent: Wednesday, August 27, 2025 6:04 PM > To: Kyrylo Tkachov <ktkac...@nvidia.com> > Cc: GCC Patches <gcc-patches@gcc.gnu.org>; 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 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; > +}