From: Adhemerval Zanella Date: Fri, 1 Apr 2022 19:54:55 +0000 (-0300) Subject: x86: Do not use __builtin_fpclassify on clang X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=603291df30ee7da3ca8da9db003d1e696b0fd20c;p=thirdparty%2Fglibc.git 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 --- 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 + . */ + +#ifndef _MATH_H +# error "Never use directly; include 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 94258d160c..ebcb2b2216 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 d97f33a828..a26a5c530b 100644 --- a/math/math.h +++ b/math/math.h @@ -919,6 +919,8 @@ enum FP_NORMAL }; +#include + /* 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. */ @@ -926,6 +928,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 @@ -967,7 +970,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 + . */ + +#ifndef _MATH_H +# error "Never use directly; include instead." +#endif + +/* clang does not handle pseudo-normal with builtins. */ +#ifdef __clang__ +# define __FP_BUILTIN_DENORMAL 0 +#else +# define __FP_BUILTIN_DENORMAL 1 +#endif