From 9bd3ef8e19b19fb3cfcf99a33a1493035891b990 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Wed, 8 Jun 2016 21:55:06 +0000 Subject: [PATCH] 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. --- ChangeLog | 8 ++++++++ math/libm-test.inc | 6 ++++++ sysdeps/i386/fpu/e_expl.S | 7 +++++-- sysdeps/x86_64/fpu/e_expl.S | 7 +++++-- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index cf5e480bbfe..0d140aab661 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2016-06-08 Joseph Myers + [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. diff --git a/math/libm-test.inc b/math/libm-test.inc index 583c27cfc06..35a256c485b 100644 --- a/math/libm-test.inc +++ b/math/libm-test.inc @@ -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), }; diff --git a/sysdeps/i386/fpu/e_expl.S b/sysdeps/i386/fpu/e_expl.S index 64e0d96839f..7d75fe22a1b 100644 --- a/sysdeps/i386/fpu/e_expl.S +++ b/sysdeps/i386/fpu/e_expl.S @@ -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) diff --git a/sysdeps/x86_64/fpu/e_expl.S b/sysdeps/x86_64/fpu/e_expl.S index 8b3ddaec597..a4ef023b2bf 100644 --- a/sysdeps/x86_64/fpu/e_expl.S +++ b/sysdeps/x86_64/fpu/e_expl.S @@ -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) -- 2.47.2