[v3,1/3] math: move the classification macros to bits/fpclassify.h

Message ID 20260911233517.2113403-1-mattst88@gmail.com (mailing list archive)
State Under Review
Delegated to: Adhemerval Zanella Netto
Headers
Series [v3,1/3] math: move the classification macros to bits/fpclassify.h |

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 fail Test failed
linaro-tcwg-bot/tcwg_glibc_check--master-arm success Test passed

Commit Message

Matt Turner Sept. 11, 2026, 11:35 p.m. UTC
  fpclassify, isfinite, isnormal, isnan and isinf expand to floating-point
comparisons wherever the compiler builtins do, and a machine may not be able
to classify a value that way.  Move them to a new bits/fpclassify.h so that
such a machine can override them.

signbit moves ahead of the moved macros to keep them contiguous.  It is
unaffected, as it is not defined in terms of a comparison.

No functional change.
---
 bits/fpclassify.h | 85 +++++++++++++++++++++++++++++++++++++++++++++++
 math/Makefile     |  1 +
 math/math.h       | 64 +----------------------------------
 3 files changed, 87 insertions(+), 63 deletions(-)
 create mode 100644 bits/fpclassify.h
  

Comments

Matt Turner Oct. 2, 2026, 9:43 p.m. UTC | #1
On Fri, Sep 11, 2026 at 7:35 PM Matt Turner <mattst88@gmail.com> wrote:
>
> fpclassify, isfinite, isnormal, isnan and isinf expand to floating-point
> comparisons wherever the compiler builtins do, and a machine may not be able
> to classify a value that way.  Move them to a new bits/fpclassify.h so that
> such a machine can override them.
>
> signbit moves ahead of the moved macros to keep them contiguous.  It is
> unaffected, as it is not defined in terms of a comparison.
>
> No functional change.

Ping for review.
  

Patch

diff --git ./bits/fpclassify.h ./bits/fpclassify.h
new file mode 100644
index 0000000000..939bbb8a81
--- /dev/null
+++ ./bits/fpclassify.h
@@ -0,0 +1,85 @@ 
+/* Define floating-point classification macros.
+   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_H
+# error "Never use <bits/fpclassify.h> directly; include <math.h> instead."
+#endif
+
+/* GCC bug 66462 means we cannot use the math builtins with -fsignaling-nan,
+   so disable builtins if this is enabled.  When fixed in a newer GCC,
+   the __SUPPORT_SNAN__ check may be skipped for those versions.  */
+
+/* Return number of classification appropriate for X.  */
+#if ((__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__)			      \
+     || __glibc_clang_prereq (2,8))					      \
+    && (!defined __OPTIMIZE_SIZE__ || defined __cplusplus)
+ /* The check for __cplusplus allows the use of the builtin, even
+    when optimization for size is on.  This is provided for
+    libstdc++, only to let its configure test work when it is built
+    with -Os.  No further use of this definition of fpclassify is
+    expected in C++ mode, since libstdc++ provides its own version
+    of fpclassify in cmath (which undefines fpclassify).  */
+# define fpclassify(x) __builtin_fpclassify (FP_NAN, FP_INFINITE,	      \
+    FP_NORMAL, FP_SUBNORMAL, FP_ZERO, x)
+#else
+# define fpclassify(x) __MATH_TG ((x), __fpclassify, (x))
+#endif
+
+/* Return nonzero value if X is not +-Inf or NaN.  */
+#if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
+    || __glibc_clang_prereq (2,8)
+# define isfinite(x) __builtin_isfinite (x)
+#else
+# define isfinite(x) __MATH_TG ((x), __finite, (x))
+#endif
+
+/* Return nonzero value if X is neither zero, subnormal, Inf, nor NaN.  */
+#if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
+    || __glibc_clang_prereq (2,8)
+# define isnormal(x) __builtin_isnormal (x)
+#else
+# define isnormal(x) (fpclassify (x) == FP_NORMAL)
+#endif
+
+/* Return nonzero value if X is a NaN.  We could use `fpclassify' but
+   we already have this functions `__isnan' and it is faster.  */
+#if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
+    || __glibc_clang_prereq (2,8)
+# define isnan(x) __builtin_isnan (x)
+#else
+# define isnan(x) __MATH_TG ((x), __isnan, (x))
+#endif
+
+/* Return nonzero value if X is positive or negative infinity.  */
+#if __HAVE_DISTINCT_FLOAT128 && !__GNUC_PREREQ (7,0) \
+    && !defined __SUPPORT_SNAN__ && !defined __cplusplus \
+    && !defined __clang__
+ /* Since __builtin_isinf_sign is broken for float128 before GCC 7.0,
+    use the helper function, __isinff128, with older compilers.  This is
+    only provided for C mode, because in C++ mode, GCC has no support
+    for __builtin_types_compatible_p (and when in C++ mode, this macro is
+    not used anyway, because libstdc++ headers undefine it).  */
+# define isinf(x) \
+   (__builtin_types_compatible_p (__typeof (x), _Float128) \
+    ? __isinff128 (x) : __builtin_isinf_sign (x))
+#elif (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
+      || __glibc_clang_prereq (3,7)
+# define isinf(x) __builtin_isinf_sign (x)
+#else
+# define isinf(x) __MATH_TG ((x), __isinf, (x))
+#endif
diff --git ./math/Makefile ./math/Makefile
index 5b48e53300..d9b17a8277 100644
--- ./math/Makefile
+++ ./math/Makefile
@@ -30,6 +30,7 @@  headers := \
   bits/flt-eval-method.h \
   bits/fp-fast.h \
   bits/fp-logb.h \
+  bits/fpclassify.h \
   bits/iscanonical.h \
   bits/libm-simd-decl-stubs.h \
   bits/long-double.h \
diff --git ./math/math.h ./math/math.h
index 75830d7696..0926b418a5 100644
--- ./math/math.h
+++ ./math/math.h
@@ -1087,26 +1087,6 @@  enum
       FP_NORMAL
   };
 
-/* GCC bug 66462 means we cannot use the math builtins with -fsignaling-nan,
-   so disable builtins if this is enabled.  When fixed in a newer GCC,
-   the __SUPPORT_SNAN__ check may be skipped for those versions.  */
-
-/* Return number of classification appropriate for X.  */
-# if ((__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__)		      \
-      || __glibc_clang_prereq (2,8))					      \
-     && (!defined __OPTIMIZE_SIZE__ || defined __cplusplus)
-     /* The check for __cplusplus allows the use of the builtin, even
-	when optimization for size is on.  This is provided for
-	libstdc++, only to let its configure test work when it is built
-	with -Os.  No further use of this definition of fpclassify is
-	expected in C++ mode, since libstdc++ provides its own version
-	of fpclassify in cmath (which undefines fpclassify).  */
-#  define fpclassify(x) __builtin_fpclassify (FP_NAN, FP_INFINITE,	      \
-     FP_NORMAL, FP_SUBNORMAL, FP_ZERO, x)
-# else
-#  define fpclassify(x) __MATH_TG ((x), __fpclassify, (x))
-# endif
-
 /* Return nonzero value if sign of X is negative.  */
 # if __GNUC_PREREQ (6,0) || __glibc_clang_prereq (3,3)
 #  define signbit(x) __builtin_signbit (x)
@@ -1125,49 +1105,7 @@  enum
 #  define signbit(x) __MATH_TG ((x), __signbit, (x))
 # endif
 
-/* Return nonzero value if X is not +-Inf or NaN.  */
-# if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
-     || __glibc_clang_prereq (2,8)
-#  define isfinite(x) __builtin_isfinite (x)
-# else
-#  define isfinite(x) __MATH_TG ((x), __finite, (x))
-# endif
-
-/* Return nonzero value if X is neither zero, subnormal, Inf, nor NaN.  */
-# if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
-     || __glibc_clang_prereq (2,8)
-#  define isnormal(x) __builtin_isnormal (x)
-# else
-#  define isnormal(x) (fpclassify (x) == FP_NORMAL)
-# endif
-
-/* Return nonzero value if X is a NaN.  We could use `fpclassify' but
-   we already have this functions `__isnan' and it is faster.  */
-# if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
-     || __glibc_clang_prereq (2,8)
-#  define isnan(x) __builtin_isnan (x)
-# else
-#  define isnan(x) __MATH_TG ((x), __isnan, (x))
-# endif
-
-/* Return nonzero value if X is positive or negative infinity.  */
-# if __HAVE_DISTINCT_FLOAT128 && !__GNUC_PREREQ (7,0) \
-     && !defined __SUPPORT_SNAN__ && !defined __cplusplus \
-     && !defined __clang__
-   /* Since __builtin_isinf_sign is broken for float128 before GCC 7.0,
-      use the helper function, __isinff128, with older compilers.  This is
-      only provided for C mode, because in C++ mode, GCC has no support
-      for __builtin_types_compatible_p (and when in C++ mode, this macro is
-      not used anyway, because libstdc++ headers undefine it).  */
-#  define isinf(x) \
-    (__builtin_types_compatible_p (__typeof (x), _Float128) \
-     ? __isinff128 (x) : __builtin_isinf_sign (x))
-# elif (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
-       || __glibc_clang_prereq (3,7)
-#  define isinf(x) __builtin_isinf_sign (x)
-# else
-#  define isinf(x) __MATH_TG ((x), __isinf, (x))
-# endif
+# include <bits/fpclassify.h>
 
 /* Bitmasks for the math_errhandling macro.  */
 # define MATH_ERRNO	1	/* errno set by math functions.  */