aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilco Dijkstra <wilco.dijkstra@arm.com>2025-08-13 14:56:57 +0000
committerWilco Dijkstra <wilco.dijkstra@arm.com>2025-08-28 14:12:04 +0000
commit8187d2630fac77176a4a806a60b0399a1e0376d8 (patch)
tree946dca0d8b6fcb22e1a7f04b85387848002587c7
parentf4b96998f1c1aa22c70462d018f8a3d4a8ec214a (diff)
downloadgcc-8187d2630fac77176a4a806a60b0399a1e0376d8.zip
gcc-8187d2630fac77176a4a806a60b0399a1e0376d8.tar.gz
gcc-8187d2630fac77176a4a806a60b0399a1e0376d8.tar.bz2
AArch64: Add isinf expander [PR 66462]
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. gcc/testsuite: PR middle-end/66462 * gcc.target/aarch64/pr66462.c: Add new test.
-rw-r--r--gcc/config/aarch64/aarch64.md18
-rw-r--r--gcc/config/aarch64/iterators.md2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr66462.c45
3 files changed, 64 insertions, 1 deletions
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index fedbd40..6e215c4 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -4507,7 +4507,7 @@
[(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")
@@ -7690,6 +7690,22 @@
}
)
+(define_expand "isinf<mode>2"
+ [(match_operand:SI 0 "register_operand")
+ (match_operand:GPF 1 "register_operand")]
+ "TARGET_FLOAT"
+{
+ rtx op = force_lowpart_subreg (<V_INT_EQUIV>mode, operands[1], <MODE>mode);
+ 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 c3771d9..b15e578 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -1340,6 +1340,8 @@
(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 0000000..9ebd48e
--- /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;
+}