Fix i386/x86_64 expl, exp10l, expm1l for sNaN input (bug 20226).

The i386 and x86_64 implementations of expl, exp10l and expm1l (code
shared between the functions) return sNaN for sNaN input.  This patch
fixes them to add NaN inputs to themselves so that qNaN is returned in
this case.

Tested for x86_64 and x86.

	[BZ #20226]
	* sysdeps/i386/fpu/e_expl.S (IEEE754_EXPL): Add NaN argument to
	itself.
	* sysdeps/x86_64/fpu/e_expl.S (IEEE754_EXPL): Likewise.
	* math/libm-test.inc (exp_test_data): Add sNaN tests.
	(exp10_test_data): Likewise.
	(expm1_test_data): Likewise.
This commit is contained in:
Joseph Myers 2016-06-08 21:55:06 +00:00
parent 9946e7a949
commit 9bd3ef8e19
4 changed files with 24 additions and 4 deletions

View File

@ -1,5 +1,13 @@
2016-06-08 Joseph Myers <joseph@codesourcery.com>
[BZ #20226]
* sysdeps/i386/fpu/e_expl.S (IEEE754_EXPL): Add NaN argument to
itself.
* sysdeps/x86_64/fpu/e_expl.S (IEEE754_EXPL): Likewise.
* math/libm-test.inc (exp_test_data): Add sNaN tests.
(exp10_test_data): Likewise.
(expm1_test_data): Likewise.
[BZ #20225]
* math/s_ldexp.c (__ldexp): Add non-finite or zero argument to
itself.

View File

@ -6992,6 +6992,8 @@ static const struct test_f_f_data exp_test_data[] =
TEST_f_f (exp, minus_infty, 0, ERRNO_UNCHANGED|NO_TEST_INLINE),
TEST_f_f (exp, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_f_f (exp, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_f_f (exp, snan_value, qnan_value, INVALID_EXCEPTION),
TEST_f_f (exp, -snan_value, qnan_value, INVALID_EXCEPTION),
AUTO_TESTS_f_f (exp),
};
@ -7009,6 +7011,8 @@ static const struct test_f_f_data exp10_test_data[] =
TEST_f_f (exp10, minus_infty, 0, ERRNO_UNCHANGED),
TEST_f_f (exp10, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_f_f (exp10, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_f_f (exp10, snan_value, qnan_value, INVALID_EXCEPTION),
TEST_f_f (exp10, -snan_value, qnan_value, INVALID_EXCEPTION),
AUTO_TESTS_f_f (exp10),
};
@ -7052,6 +7056,8 @@ static const struct test_f_f_data expm1_test_data[] =
TEST_f_f (expm1, minus_infty, -1, ERRNO_UNCHANGED|NO_TEST_INLINE),
TEST_f_f (expm1, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_f_f (expm1, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_f_f (expm1, snan_value, qnan_value, INVALID_EXCEPTION),
TEST_f_f (expm1, -snan_value, qnan_value, INVALID_EXCEPTION),
AUTO_TESTS_f_f (expm1),
};

View File

@ -102,7 +102,7 @@ ENTRY(IEEE754_EXPL)
/* Below -64.0 (may be -NaN or -Inf). */
andb %ah, %dh
cmpb $0x01, %dh
je 2f /* Is +-NaN, jump. */
je 6f /* Is +-NaN, jump. */
jmp 1f /* -large, possibly -Inf. */
4: /* In range -64.0 to 64.0 (may be +-0 but not NaN or +-Inf). */
@ -144,7 +144,7 @@ ENTRY(IEEE754_EXPL)
cmpb $0x05, %dh
je 1f /* Is +-Inf, jump. */
cmpb $0x01, %dh
je 2f /* Is +-NaN, jump. */
je 6f /* Is +-NaN, jump. */
/* Overflow or underflow; saturate. */
fstp %st
fldt MO(csat)
@ -214,6 +214,9 @@ ENTRY(IEEE754_EXPL)
fldz /* Set result to 0. */
#endif
2: ret
6: /* NaN argument. */
fadd %st
ret
END(IEEE754_EXPL)
#ifdef USE_AS_EXPM1L
libm_hidden_def (__expm1l)

View File

@ -99,7 +99,7 @@ ENTRY(IEEE754_EXPL)
/* Below -64.0 (may be -NaN or -Inf). */
andb %ah, %dh
cmpb $0x01, %dh
je 2f /* Is +-NaN, jump. */
je 6f /* Is +-NaN, jump. */
jmp 1f /* -large, possibly -Inf. */
4: /* In range -64.0 to 64.0 (may be +-0 but not NaN or +-Inf). */
@ -141,7 +141,7 @@ ENTRY(IEEE754_EXPL)
cmpb $0x05, %dh
je 1f /* Is +-Inf, jump. */
cmpb $0x01, %dh
je 2f /* Is +-NaN, jump. */
je 6f /* Is +-NaN, jump. */
/* Overflow or underflow; saturate. */
fstp %st
fldt MO(csat)
@ -207,6 +207,9 @@ ENTRY(IEEE754_EXPL)
fldz /* Set result to 0. */
#endif
2: ret
6: /* NaN argument. */
fadd %st
ret
END(IEEE754_EXPL)
#ifdef USE_AS_EXPM1L
libm_hidden_def (__expm1l)