On FreeBSD 12.2/arm, a unit test fails: ../../gltests/test-fma2.h:351: assertion 'result == expected' failed
This patch fixes it. The same test failure also occurs on FreeBSD 12.2/arm64, with the same values for x, y, z. But the added configure test does not fix it. It is as if the same fmaf() invocation produces the correct result in the configure test but the wrong result later, during the unit test. I don't understand it. 2020-12-09 Bruno Haible <br...@clisp.org> fmaf: Work around a bug on FreeBSD 12.2/arm. * m4/fmaf.m4 (gl_FUNC_FMAF_WORKS): Add one more test. * doc/posix-functions/fmaf.texi: Mention the FreeBSD bug. diff --git a/doc/posix-functions/fmaf.texi b/doc/posix-functions/fmaf.texi index 0515acd..1e0d34a 100644 --- a/doc/posix-functions/fmaf.texi +++ b/doc/posix-functions/fmaf.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, MSVC 9. @item This function produces wrong results on some platforms: -glibc 2.11, Mac OS X 10.5, FreeBSD 6.4/x86, Cygwin 1.5, mingw. +glibc 2.11, Mac OS X 10.5, FreeBSD 6.4/x86, FreeBSD 12.2/arm, Cygwin 1.5, mingw. @end itemize Portability problems not fixed by Gnulib: diff --git a/m4/fmaf.m4 b/m4/fmaf.m4 index bad747e..4387d57 100644 --- a/m4/fmaf.m4 +++ b/m4/fmaf.m4 @@ -1,4 +1,4 @@ -# fmaf.m4 serial 5 +# fmaf.m4 serial 6 dnl Copyright (C) 2011-2020 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -167,6 +167,21 @@ int main() if (!(result == minus_inf)) failed_tests |= 64; } + /* This test fails on FreeBSD 12.2/arm. */ + if ((FLT_MANT_DIG % 2) == 0) + { + volatile float x = 1.0f + ldexpf (1.0f, - FLT_MANT_DIG / 2); /* 2^0 + 2^-12 */ + volatile float y = x; + volatile float z = - ldexpf (1.0f, FLT_MIN_EXP - FLT_MANT_DIG); /* 2^-149 */ + /* x * y + z with infinite precision: 2^0 + 2^-11 + 2^-24 - 2^-149. + Lies between (2^23 + 2^12 + 0) * 2^-23 and (2^23 + 2^12 + 1) * 2^-23 + and is closer to (2^23 + 2^12 + 0) * 2^-23, therefore the rounding + must round down and produce (2^23 + 2^12 + 0) * 2^-23. */ + volatile float expected = 1.0f + ldexpf (1.0f, 1 - FLT_MANT_DIG / 2); + volatile float result = fmaf (x, y, z); + if (result != expected) + failed_tests |= 32; + } return failed_tests; }]])], [gl_cv_func_fmaf_works=yes],