summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2022-04-01 16:54:55 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2025-11-20 14:53:07 -0300
commitc92cb4f094d76f95a8b162ecfbb6e9577d7c4845 (patch)
treedc34b2bb499b305b151ff46a1fd301b59b23ca4b
parente6f50abbb623025fbe5b59211dc186653b7d1f05 (diff)
x86: Do not use __builtin_fpclassify on clang
clang does not handle pseudo normal numbers, so disable the fpclassify and isnormal builtin optimization if clang is used. This only affect x86, so add a new header, fp-builtin-denormal.h, which defines whether the architecture required to disable the optimization through a new glibc define (__FP_BUILTIN_DENORMAL). It fixes the regression on test-ldouble-fpclassify and test-float64x-fpclassify when built with clang: Failure: fpclassify (pseudo_zero): Exception "Invalid operation" set Failure: fpclassify (pseudo_inf): Exception "Invalid operation" set Failure: fpclassify (pseudo_qnan): Exception "Invalid operation" set Failure: fpclassify (pseudo_snan): Exception "Invalid operation" set Failure: fpclassify (pseudo_unnormal): Exception "Invalid operation" set Failure: fpclassify_downward (pseudo_zero): Exception "Invalid operation" set Failure: fpclassify_downward (pseudo_inf): Exception "Invalid operation" set Failure: fpclassify_downward (pseudo_qnan): Exception "Invalid operation" set Failure: fpclassify_downward (pseudo_snan): Exception "Invalid operation" set Failure: fpclassify_downward (pseudo_unnormal): Exception "Invalid operation" set Failure: fpclassify_towardzero (pseudo_zero): Exception "Invalid operation" set Failure: fpclassify_towardzero (pseudo_inf): Exception "Invalid operation" set Failure: fpclassify_towardzero (pseudo_qnan): Exception "Invalid operation" set Failure: fpclassify_towardzero (pseudo_snan): Exception "Invalid operation" set Failure: fpclassify_towardzero (pseudo_unnormal): Exception "Invalid operation" set Failure: fpclassify_upward (pseudo_zero): Exception "Invalid operation" set Failure: fpclassify_upward (pseudo_inf): Exception "Invalid operation" set Failure: fpclassify_upward (pseudo_qnan): Exception "Invalid operation" set Failure: fpclassify_upward (pseudo_snan): Exception "Invalid operation" set Failure: fpclassify_upward (pseudo_unnormal): Exception "Invalid operation" set
-rw-r--r--bits/fp-builtin-denormal.h27
-rw-r--r--math/Makefile1
-rw-r--r--math/math.h6
-rw-r--r--sysdeps/x86/bits/fp-builtin-denormal.h28
4 files changed, 61 insertions, 1 deletions
diff --git a/bits/fp-builtin-denormal.h b/bits/fp-builtin-denormal.h
new file mode 100644
index 0000000000..08df8758f6
--- /dev/null
+++ b/bits/fp-builtin-denormal.h
@@ -0,0 +1,27 @@
+/* Define __FP_BUILTIN_DENORMAL.
+ Copyright (C) 2025 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/fp-builtin-denormal.h> directly; include <math.h> instead."
+#endif
+
+/* __FP_BUILTIN_DENORMAL is define to 1 if compiler supports handling
+ pseudo-normal numbers with builtins. Pseudo-normal are defined onlyi
+ Intel double extended-precision floating point (long double), so
+ assume 1 to enable the math optimization. */
+#define __FP_BUILTIN_DENORMAL 1
diff --git a/math/Makefile b/math/Makefile
index f7a1d9016c..8fe2540ce0 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -28,6 +28,7 @@ headers := \
bits/floatn-common.h \
bits/floatn.h \
bits/flt-eval-method.h \
+ bits/fp-builtin-denormal.h \
bits/fp-fast.h \
bits/fp-logb.h \
bits/iscanonical.h \
diff --git a/math/math.h b/math/math.h
index 8e904e5d93..2676896c64 100644
--- a/math/math.h
+++ b/math/math.h
@@ -1083,6 +1083,8 @@ enum
FP_NORMAL
};
+#include <bits/fp-builtin-denormal.h>
+
/* 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. */
@@ -1090,6 +1092,7 @@ enum
/* Return number of classification appropriate for X. */
# if ((__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
|| __glibc_clang_prereq (2,8)) \
+ && __FP_BUILTIN_DENORMAL \
&& (!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
@@ -1131,7 +1134,8 @@ enum
/* 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)
+ || __glibc_clang_prereq (2,8) \
+ && __FP_BUILTIN_DENORMAL
# define isnormal(x) __builtin_isnormal (x)
# else
# define isnormal(x) (fpclassify (x) == FP_NORMAL)
diff --git a/sysdeps/x86/bits/fp-builtin-denormal.h b/sysdeps/x86/bits/fp-builtin-denormal.h
new file mode 100644
index 0000000000..a8c1ca0251
--- /dev/null
+++ b/sysdeps/x86/bits/fp-builtin-denormal.h
@@ -0,0 +1,28 @@
+/* Define __FP_BUILTIN_DENORMAL.
+ Copyright (C) 2025 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/fp-builtin-denormal.h> directly; include <math.h> instead."
+#endif
+
+/* clang does not handle pseudo-normal with builtins. */
+#ifdef __clang__
+# define __FP_BUILTIN_DENORMAL 0
+#else
+# define __FP_BUILTIN_DENORMAL 1
+#endif