On CentOS 7 / x86_64 (with glibc 2.17), I see a 'test-fmal2' failure. The local variables at test-fma2.h:116 are:
xs = 0 xe = 0 x = 1 ys = 0 ye = 0 y = 1 sign = 1 ze = -65 z = -2.710...e-20 x * y + z = 1 * 1 - 2^-65 This test case is not yet among the ones tested by the configure script, therefore configure has incorrectly determined that fmal() works. The fix is simply to add this test case. 2022-09-03 Bruno Haible <[email protected]> fmal: Work around glibc 2.17 bug on x86_64. * m4/fmal.m4 (gl_FUNC_FMAL_WORKS): Test against bug seen on glibc 2.17 x86_64. * doc/posix-functions/fmal.texi: Update info. diff --git a/doc/posix-functions/fmal.texi b/doc/posix-functions/fmal.texi index 1c9db7a9c0..99223b317a 100644 --- a/doc/posix-functions/fmal.texi +++ b/doc/posix-functions/fmal.texi @@ -13,7 +13,7 @@ This function is missing on some platforms: FreeBSD 5.2.1, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 9, Cygwin 1.7.x, MSVC 9, Android 4.4. @item This function produces wrong results on some platforms: -glibc 2.11, macOS 10.13, FreeBSD 6.4/x86, mingw. +glibc 2.17, macOS 10.13, FreeBSD 6.4/x86, mingw. @end itemize Portability problems not fixed by Gnulib: diff --git a/m4/fmal.m4 b/m4/fmal.m4 index c7d4f346e2..9d78a2817b 100644 --- a/m4/fmal.m4 +++ b/m4/fmal.m4 @@ -1,4 +1,4 @@ -# fmal.m4 serial 7 +# fmal.m4 serial 8 dnl Copyright (C) 2011-2022 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -65,7 +65,8 @@ AC_DEFUN([gl_FUNC_FMAL], AC_SUBST([FMAL_LIBM]) ]) -dnl Test whether fmal() has any of the 15 known bugs of glibc 2.11.3 on x86_64. +dnl Test whether fmal() has any of the 15 known bugs of glibc 2.11.3 on x86_64 +dnl or the known bug of glibc 2.17 on x86_64. AC_DEFUN([gl_FUNC_FMAL_WORKS], [ AC_REQUIRE([AC_PROG_CC]) @@ -365,6 +366,20 @@ int main() if (result != expected) failed_tests |= 32; } + /* This test fails on glibc 2.17 x86_64. */ + { + volatile long double x = 1.0L; + volatile long double y = x; + volatile long double z = - ldexpl (1.0L, -1 - LDBL_MANT_DIG); /* - 2^-65 */ + /* x * y + z with infinite precision: 2^0 - 2^-65. + Lies between 2^0 - 2^-64 and 2^0 and is at the same distance from each. + According to the round-to-even rule, the rounding must round up and + produce 2^0. */ + volatile long double expected = 1.0L; + volatile long double result = fmal (x, y, z); + if (result != expected) + failed_tests |= 64; + } return failed_tests; }]])], [gl_cv_func_fmal_works=yes],
