[v3,05/12] loongarch: Add an inline roundeven_finite

Message ID 20260923215118.2608685-6-adhemerval.zanella@linaro.org (mailing list archive)
State Under Review
Delegated to: Wilco Dijkstra
Headers
Series Add sinf/cosf/sincosf CORE-MATH implementations |

Checks

Context Check Description
redhat-pt-bot/TryBot-apply_patch success Patch applied to master at the time it was sent
linaro-tcwg-bot/tcwg_glibc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_glibc_check--master-arm success Test passed

Commit Message

Adhemerval Zanella Sept. 23, 2026, 9:50 p.m. UTC
  Every range reduction that uses roundeven_finite requires a call to
__roundeven.  The FTINTRNE.L.D and FFINT.D.L pair gives the
round-to-nearest-even value in two instructions, independently of the
rounding mode, and exactly for |x| < 2^63.

On a Loongson-3C5000L-LL the CORE-MATH sinf, cosf, and sincosf of the
following patches run 14% to 16% faster with this change (geomean of
the reciprocal-throughput and latency of the benchtests inputs that
preceded the workload rewrite of this series: sinf -14.4%, cosf -15.6%,
sincosf -14.9%).

FTINTRNE raises the inexact exception for a non integer argument,
however the users of roundeven_finite (the range reductions of sinf,
cosf, sincosf, tanf, tanpif, expm1f, sinhf, coshf, gammaf, and the
double erfc, gamma, and lgamma) already produce inexact results for
such arguments anyway.

Checked on loongarch64-linux-gnuf64.
---
 sysdeps/loongarch/fpu/math-roundeven-finite.h | 44 +++++++++++++++++++
 1 file changed, 44 insertions(+)
 create mode 100644 sysdeps/loongarch/fpu/math-roundeven-finite.h
  

Comments

Xi Ruoyao Oct. 12, 2026, 1:36 a.m. UTC | #1
On Wed, 2026-09-23 at 18:50 -0300, Adhemerval Zanella wrote:
> Every range reduction that uses roundeven_finite requires a call to
> __roundeven.  The FTINTRNE.L.D and FFINT.D.L pair gives the
> round-to-nearest-even value in two instructions, independently of the
> rounding mode, and exactly for |x| < 2^63.
> 
> On a Loongson-3C5000L-LL the CORE-MATH sinf, cosf, and sincosf of the
> following patches run 14% to 16% faster with this change (geomean of
> the reciprocal-throughput and latency of the benchtests inputs that
> preceded the workload rewrite of this series: sinf -14.4%, cosf -15.6%,
> sincosf -14.9%).
> 
> FTINTRNE raises the inexact exception for a non integer argument,
> however the users of roundeven_finite (the range reductions of sinf,
> cosf, sincosf, tanf, tanpif, expm1f, sinhf, coshf, gammaf, and the
> double erfc, gamma, and lgamma) already produce inexact results for
> such arguments anyway.
> 
> Checked on loongarch64-linux-gnuf64.
> ---
>  sysdeps/loongarch/fpu/math-roundeven-finite.h | 44 +++++++++++++++++++
>  1 file changed, 44 insertions(+)
>  create mode 100644 sysdeps/loongarch/fpu/math-roundeven-finite.h
> 
> diff --git a/sysdeps/loongarch/fpu/math-roundeven-finite.h b/sysdeps/loongarch/fpu/math-roundeven-finite.h
> new file mode 100644
> index 00000000000..5d0fdd56b28
> --- /dev/null
> +++ b/sysdeps/loongarch/fpu/math-roundeven-finite.h
> @@ -0,0 +1,44 @@
> +/* Round to nearest integer, ties to even, of a finite argument.  LoongArch.

The description seems different from the implementation.  The
implementation only works when -2^{63} \leq x < 2^{63}, not any finite
|x| (for example 1.0e33 is still finite but this cannot work).

As this is already checked I'd assume the description is imprecise (and
the file name itself is a little misleading already).
  

Patch

diff --git a/sysdeps/loongarch/fpu/math-roundeven-finite.h b/sysdeps/loongarch/fpu/math-roundeven-finite.h
new file mode 100644
index 00000000000..5d0fdd56b28
--- /dev/null
+++ b/sysdeps/loongarch/fpu/math-roundeven-finite.h
@@ -0,0 +1,44 @@ 
+/* Round to nearest integer, ties to even, of a finite argument.  LoongArch.
+   Copyright (C) 2026 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _MATH_ROUNDEVEN_FINITE_H
+#define _MATH_ROUNDEVEN_FINITE_H 1
+
+/* The result is exact for |x| < 2^63. FTINTRNE also raises the inexact
+   the current usage tolerates it.  */
+static inline double
+roundeven_finite (double x)
+{
+  double r;
+  __asm__ ("ftintrne.l.d %0, %1\n\t"
+	   "ffint.d.l %0, %0"
+	   : "=f" (r) : "f" (x));
+  return r;
+}
+
+static inline float
+roundevenf_finite (float x)
+{
+  float r;
+  __asm__ ("ftintrne.l.s %0, %1\n\t"
+	   "ffint.s.l %0, %0"
+	   : "=f" (r) : "f" (x));
+  return r;
+}
+
+#endif