[v3,04/12] math: Make roundeven_finite an architecture hook

Message ID 20260923215118.2608685-5-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
  Move the alternative to a new sysdeps header (math-roundeven-finite),
the ROUNDEVEN_INTRINSICS and ROUNDEVENF_INTRINSICS macros are gone.

Also use stdc_trailing_zeros instead of __builtin_ctzll for the
powerpc version.

Checked with a build on x86_64-linux-gnu, aarch64-linux-gnu, and
powerpc64le-linux-gnu, and powerpc-linux-gnu.
---
 sysdeps/generic/math-roundeven-finite.h     | 40 ++++++++++++++
 sysdeps/ieee754/dbl-64/math_config.h        | 27 +---------
 sysdeps/ieee754/flt-32/math_config.h        | 52 +-----------------
 sysdeps/powerpc/fpu/math-roundeven-finite.h | 60 +++++++++++++++++++++
 sysdeps/powerpc/fpu/math_private.h          |  6 ---
 5 files changed, 102 insertions(+), 83 deletions(-)
 create mode 100644 sysdeps/generic/math-roundeven-finite.h
 create mode 100644 sysdeps/powerpc/fpu/math-roundeven-finite.h
  

Patch

diff --git a/sysdeps/generic/math-roundeven-finite.h b/sysdeps/generic/math-roundeven-finite.h
new file mode 100644
index 00000000000..09c96d6d0ad
--- /dev/null
+++ b/sysdeps/generic/math-roundeven-finite.h
@@ -0,0 +1,40 @@ 
+/* Round to nearest integer, ties to even, of a finite argument.  Generic.
+   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
+
+/* Round x to nearest integer value in floating-point format, rounding halfway
+  cases to even.  If the input is non finite the result is unspecified.  */
+static inline double
+roundeven_finite (double x)
+{
+  if (!isfinite (x))
+    __builtin_unreachable ();
+  return roundeven (x);
+}
+
+static inline float
+roundevenf_finite (float x)
+{
+  if (!isfinite (x))
+    __builtin_unreachable ();
+  return roundevenf (x);
+}
+
+#endif /* math-roundeven-finite.h */
diff --git a/sysdeps/ieee754/dbl-64/math_config.h b/sysdeps/ieee754/dbl-64/math_config.h
index 6a1f3062f84..ac2cf8000d2 100644
--- a/sysdeps/ieee754/dbl-64/math_config.h
+++ b/sysdeps/ieee754/dbl-64/math_config.h
@@ -38,32 +38,7 @@ 
 # define WANT_ERRNO_UFLOW (WANT_ROUNDING && WANT_ERRNO)
 #endif
 
-#ifndef ROUNDEVEN_INTRINSICS
-/* When set, roundeven_finite will route to the internal roundeven function.  */
-# define ROUNDEVEN_INTRINSICS 1
-#endif
-
-/* Round x to nearest integer value in floating-point format, rounding halfway
-  cases to even.  If the input is non finite the result is unspecified.  */
-static inline double
-roundeven_finite (double x)
-{
-  if (!isfinite (x))
-    __builtin_unreachable ();
-#if ROUNDEVEN_INTRINSICS
-  return roundeven (x);
-#else
-  double y = round (x);
-  if (fabs (x - y) == 0.5)
-    {
-      union { double f; uint64_t i; } u = {y};
-      union { double f; uint64_t i; } v = {y - copysign (1.0, x)};
-      if (__builtin_ctzll (v.i) > __builtin_ctzll (u.i))
-        y = v.f;
-    }
-  return y;
-#endif
-}
+#include <math-roundeven-finite.h>
 
 #ifndef TOINT_INTRINSICS
 /* When set, the roundtoint and converttoint functions are provided with
diff --git a/sysdeps/ieee754/flt-32/math_config.h b/sysdeps/ieee754/flt-32/math_config.h
index 1509c2ef626..3b2ce81c197 100644
--- a/sysdeps/ieee754/flt-32/math_config.h
+++ b/sysdeps/ieee754/flt-32/math_config.h
@@ -58,57 +58,7 @@  static inline int32_t
 converttoint (double x);
 #endif
 
-#ifndef ROUNDEVEN_INTRINSICS
-/* When set, roundeven_finite will route to the internal roundeven function.  */
-# define ROUNDEVEN_INTRINSICS 1
-#endif
-
-/* Round x to nearest integer value in floating-point format, rounding halfway
-  cases to even.  If the input is non finite the result is unspecified.  */
-static inline double
-roundeven_finite (double x)
-{
-  if (!isfinite (x))
-    __builtin_unreachable ();
-#if ROUNDEVEN_INTRINSICS
-  return roundeven (x);
-#else
-  double y = round (x);
-  if (fabs (x - y) == 0.5)
-    {
-      union { double f; uint64_t i; } u = {y};
-      union { double f; uint64_t i; } v = {y - copysign (1.0, x)};
-      if (stdc_trailing_zeros (v.i) > stdc_trailing_zeros (u.i))
-        y = v.f;
-    }
-  return y;
-#endif
-}
-
-#ifndef ROUNDEVENF_INTRINSICS
-/* When set, roundevenf_finite will route to the internal roundevenf function.  */
-# define ROUNDEVENF_INTRINSICS 1
-#endif
-
-static inline float
-roundevenf_finite (float x)
-{
-  if (!isfinite (x))
-    __builtin_unreachable ();
-#if ROUNDEVENF_INTRINSICS
-  return roundevenf (x);
-#else
-  float y = roundf (x);
-  if (fabs (x - y) == 0.5)
-    {
-      union { float f; uint32_t i; } u = {y};
-      union { float f; uint32_t i; } v = {y - copysignf (1.0f, x)};
-      if (stdc_trailing_zeros (v.i) > stdc_trailing_zeros (u.i))
-        y = v.f;
-    }
-  return y;
-#endif
-}
+#include <math-roundeven-finite.h>
 
 static inline uint32_t
 asuint (float f)
diff --git a/sysdeps/powerpc/fpu/math-roundeven-finite.h b/sysdeps/powerpc/fpu/math-roundeven-finite.h
new file mode 100644
index 00000000000..23f3d3e30aa
--- /dev/null
+++ b/sysdeps/powerpc/fpu/math-roundeven-finite.h
@@ -0,0 +1,60 @@ 
+/* Round to nearest integer, ties to even, of a finite argument.  PowerPC.
+   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_POWERPC_H
+#define _MATH_ROUNDEVEN_FINITE_POWERPC_H 1
+
+#ifdef _ARCH_PWR6
+# include <math.h>
+# include <stdbit.h>
+# include <stdint.h>
+
+/* ISA 2.03 provides frin/round() and cntlzw/ctznll().  */
+
+static inline double
+roundeven_finite (double x)
+{
+  double y = round (x);
+  if (fabs (x - y) == 0.5)
+    {
+      union { double f; uint64_t i; } u = {y};
+      union { double f; uint64_t i; } v = {y - copysign (1.0, x)};
+      if (stdc_trailing_zeros (v.i) > stdc_trailing_zeros (u.i))
+        y = v.f;
+    }
+  return y;
+}
+
+static inline float
+roundevenf_finite (float x)
+{
+  float y = roundf (x);
+  if (fabsf (x - y) == 0.5f)
+    {
+      union { float f; uint32_t i; } u = {y};
+      union { float f; uint32_t i; } v = {y - copysignf (1.0f, x)};
+      if (stdc_trailing_zeros (v.i) > stdc_trailing_zeros (u.i))
+        y = v.f;
+    }
+  return y;
+}
+#else
+# include_next <math-roundeven-finite.h>
+#endif
+
+#endif /* math-roundeven-finite.h */
diff --git a/sysdeps/powerpc/fpu/math_private.h b/sysdeps/powerpc/fpu/math_private.h
index 7dd0675cb44..5e631ad73d2 100644
--- a/sysdeps/powerpc/fpu/math_private.h
+++ b/sysdeps/powerpc/fpu/math_private.h
@@ -58,10 +58,4 @@  __ieee754_sqrtf128 (_Float128 __x)
 #define _GL_HAS_BUILTIN_ILOGB 0
 #endif
 
-#ifdef _ARCH_PWR6
-/* ISA 2.03 provides frin/round() and cntlzw/ctznll().  */
-# define ROUNDEVEN_INTRINSICS 0
-# define ROUNDEVENF_INTRINSICS 0
-#endif
-
 #endif /* _PPC_MATH_PRIVATE_H_ */