aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilco Dijkstra <wilco.dijkstra@arm.com>2025-08-27 17:20:21 +0000
committerWilco Dijkstra <wilco.dijkstra@arm.com>2025-09-11 11:44:08 +0000
commitb996d4509f1724d92a08dae70d8354fbb5561fb7 (patch)
treeb85345cabda0860a3d37aad1e0a3c5d1fdae9e9f
parentaa4aafbad5235fd302c39e1d8b7cb9cdea11c67c (diff)
downloadgcc-b996d4509f1724d92a08dae70d8354fbb5561fb7.zip
gcc-b996d4509f1724d92a08dae70d8354fbb5561fb7.tar.gz
gcc-b996d4509f1724d92a08dae70d8354fbb5561fb7.tar.bz2
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. gcc/testsuite: PR middle-end/66462 * gcc.target/aarch64/pr66462.c: Add tests for isfinite.
-rw-r--r--gcc/config/aarch64/aarch64.md16
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr66462.c32
2 files changed, 48 insertions, 0 deletions
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 6e215c4..6d30226 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -7706,6 +7706,22 @@
}
)
+(define_expand "isfinite<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 (LTU, SImode, cc_reg, const0_rtx);
+ emit_insn (gen_aarch64_cstoresi (operands[0], cmp, cc_reg));
+ DONE;
+}
+)
+
;; -------------------------------------------------------------------
;; Reload support
;; -------------------------------------------------------------------
diff --git a/gcc/testsuite/gcc.target/aarch64/pr66462.c b/gcc/testsuite/gcc.target/aarch64/pr66462.c
index 9ebd48e..476d47c 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;
}