diff options
author | Wilco Dijkstra <wilco.dijkstra@arm.com> | 2025-08-27 17:20:21 +0000 |
---|---|---|
committer | Wilco Dijkstra <wilco.dijkstra@arm.com> | 2025-09-11 11:44:08 +0000 |
commit | b996d4509f1724d92a08dae70d8354fbb5561fb7 (patch) | |
tree | b85345cabda0860a3d37aad1e0a3c5d1fdae9e9f | |
parent | aa4aafbad5235fd302c39e1d8b7cb9cdea11c67c (diff) | |
download | gcc-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.md | 16 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/pr66462.c | 32 |
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; } |