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.
This commit is contained in:
Joseph Myers 2016-06-10 23:16:27 +00:00
parent e0835a5354
commit a6a4395d20
3 changed files with 16 additions and 0 deletions

View file

@ -1,3 +1,11 @@
2016-06-10 Joseph Myers <joseph@codesourcery.com>
[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.
2016-06-09 Carlos O'Donell <carlos@redhat.com>
[BZ #20215]

View file

@ -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.

View file

@ -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),