]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
x86: Do not use __builtin_isinf_sign for _Float64x/long double
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Fri, 19 Dec 2025 18:52:21 +0000 (15:52 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Mon, 22 Dec 2025 18:55:20 +0000 (15:55 -0300)
Neither gcc [1] nor clang [2] handles pseudo-normal numbers correctly
with the __builtin_isinf_sign, so disable its usage for _Float64x and
long double types.

This only affects x86, so add a new define __FP_BUILTIN_ISINF_SIGN_DENORMAL
to gate long double and related types to the libc function instead.

It fixes the regression on test-ldouble-isinf when built with clang:

Failure: isinf (pseudo_zero): Exception "Invalid operation" set
Failure: isinf (pseudo_inf): Exception "Invalid operation" set
Failure: isinf (pseudo_qnan): Exception "Invalid operation" set
Failure: isinf (pseudo_snan): Exception "Invalid operation" set
Failure: isinf (pseudo_unnormal): Exception "Invalid operation" set
Failure: isinf_downward (pseudo_zero): Exception "Invalid operation" set
Failure: isinf_downward (pseudo_inf): Exception "Invalid operation" set
Failure: isinf_downward (pseudo_qnan): Exception "Invalid operation" set
Failure: isinf_downward (pseudo_snan): Exception "Invalid operation" set
Failure: isinf_downward (pseudo_unnormal): Exception "Invalid operation" set
Failure: isinf_towardzero (pseudo_zero): Exception "Invalid operation" set
Failure: isinf_towardzero (pseudo_inf): Exception "Invalid operation" set
Failure: isinf_towardzero (pseudo_qnan): Exception "Invalid operation" set
Failure: isinf_towardzero (pseudo_snan): Exception "Invalid operation" set
Failure: isinf_towardzero (pseudo_unnormal): Exception "Invalid operation" set
Failure: isinf_upward (pseudo_zero): Exception "Invalid operation" set
Failure: isinf_upward (pseudo_inf): Exception "Invalid operation" set
Failure: isinf_upward (pseudo_qnan): Exception "Invalid operation" set
Failure: isinf_upward (pseudo_snan): Exception "Invalid operation" set
Failure: isinf_upward (pseudo_unnormal): Exception "Invalid operation" set

Checked on x86_64-linux-gnu with gcc-15 and clang-18.

[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123173
[2] https://github.com/llvm/llvm-project/issues/172651

Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
bits/fp-builtin-denormal.h
math/math.h
sysdeps/x86/bits/fp-builtin-denormal.h
sysdeps/x86/fpu/test-builtin-denormal.c

index 77b7184975f59a47e347a984001ce4941278f501..5748eb86f0c94f47f77bb70e1a014d5807fec210 100644 (file)
@@ -26,3 +26,7 @@
     Intel double extended-precision (long double).  By default assume 1 to
     enable the usage of compiler builtin on math.h.  */
 #define __FP_BUILTIN_FPCLASSIFY_DENORMAL 1
+
+/* __FP_BUILTIN_ISINF_SIGN_DENORMAL is defined to 1 if compiler supports
+   handling pseudo-dernormal numbers with isinf_sign builtin.  */
+#define __FP_BUILTIN_ISINF_SIGN_DENORMAL 1
index cbec2f406a0db5ae66dcaa10fb4dc7ce9cac2a3b..96b64379f742d94487530b6cb628b3833e52c06b 100644 (file)
@@ -1249,7 +1249,10 @@ enum
      ? __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)
+#  define isinf(x) __MATH_TG_BUILTIN_CLASSIFY ((x),                          \
+                                              __builtin_isinf_sign, (x),     \
+                                              isinf, (x),                    \
+                                              __FP_BUILTIN_ISINF_SIGN_DENORMAL)
 # else
 #  define isinf(x) __MATH_TG ((x), __isinf, (x))
 # endif
index bfb8f54237e4e9f093322f83032fa2c3faa972c9..2f9a5c7b66ee743ebf2a954021e563bcf79a65d1 100644 (file)
@@ -23,3 +23,7 @@
 /* Neither GCC (bug 123161) nor clang (issue 172533) handles pseudo-normal
    numbers correctly with fpclassify builtin.  */
 #define __FP_BUILTIN_FPCLASSIFY_DENORMAL 0
+
+/* Neither GCC (bug 123173) nor clang (issue 172651) handles pseudo-normal
+   numbers correctly with isinf_sign builtin.  */
+#define __FP_BUILTIN_ISINF_SIGN_DENORMAL 0
index 1fb8aeedf6f5c0311d97b58df14c0a0f443b2c76..bddcd59387bae6eba61498736720195972056077 100644 (file)
@@ -45,6 +45,10 @@ do_test (void)
       TEST_COMPARE (feclearexcept (FE_INVALID), 0);
       TEST_COMPARE (fpclassify (inputs[i].value), FP_NAN);
       TEST_COMPARE (fetestexcept (FE_INVALID), 0);
+
+      TEST_COMPARE (feclearexcept (FE_INVALID), 0);
+      TEST_COMPARE (isinf (inputs[i].value), 0);
+      TEST_COMPARE (fetestexcept (FE_INVALID), 0);
     }
 
   return 0;