diff options
author | Joseph Myers <joseph@codesourcery.com> | 2016-06-10 23:16:27 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2016-06-10 23:16:27 +0000 |
commit | a6a4395d2075228c2514c38707307be41006f498 (patch) | |
tree | 4c1f4e529d769f7fa3020e4f507e311f92ab80d6 /math | |
parent | e0835a5354aba6015648473a727823ea434a48e6 (diff) | |
download | glibc-a6a4395d2075228c2514c38707307be41006f498.tar.gz glibc-a6a4395d2075228c2514c38707307be41006f498.tar.xz glibc-a6a4395d2075228c2514c38707307be41006f498.zip |
Fix modf (sNaN) (bug 20240).
Various modf implementations return sNaN (both outputs) for sNaN input. In fact they contain code to convert sNaN to qNaN for both outputs, but the way this is done is multiplying by 1.0 (for a wider range of inputs that includes NaNs as well as numbers with exponent large enough to ensure that they are integers), and that multiplication by 1.0 is optimized away by GCC in the absence of -fsignaling-nans, unlike other operations on NaNs used for this purpose that are not no-ops for non-sNaN input. This patch arranges for those files to be built with -fsignaling-nans so that this existing code is effective as intended. Tested for x86_64 and x86. [BZ #20240] * math/Makefile (CFLAGS-s_modf.c): New variable. (CFLAGS-s_modff.c): Likewise. (CFLAGS-s_modfl.c): Likewise. * math/libm-test.inc (modf_test_data): Add sNaN tests.
Diffstat (limited to 'math')
-rw-r--r-- | math/Makefile | 6 | ||||
-rw-r--r-- | math/libm-test.inc | 2 |
2 files changed, 8 insertions, 0 deletions
diff --git a/math/Makefile b/math/Makefile index f0265bb640..6cd3cf1f65 100644 --- a/math/Makefile +++ b/math/Makefile @@ -302,6 +302,12 @@ ifneq ($(long-double-fcts),yes) math-CPPFLAGS += -DNO_LONG_DOUBLE -D_Mlong_double_=double endif +# These files quiet sNaNs in a way that is optimized away without +# -fsignaling-nans. +CFLAGS-s_modf.c += -fsignaling-nans +CFLAGS-s_modff.c += -fsignaling-nans +CFLAGS-s_modfl.c += -fsignaling-nans + # The -lieee library is actually an object file. # The module just defines the _LIB_VERSION_ variable. # It's not a library to make sure it is linked in instead of s_lib_version.o. diff --git a/math/libm-test.inc b/math/libm-test.inc index 2df6f29a34..3d901ae96a 100644 --- a/math/libm-test.inc +++ b/math/libm-test.inc @@ -9759,6 +9759,8 @@ static const struct test_fF_f1_data modf_test_data[] = TEST_fF_f1 (modf, minus_infty, minus_zero, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_fF_f1 (modf, qnan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_fF_f1 (modf, -qnan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_fF_f1 (modf, snan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_fF_f1 (modf, -snan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), TEST_fF_f1 (modf, 0, 0, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_fF_f1 (modf, minus_zero, minus_zero, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_fF_f1 (modf, min_value, min_value, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), |