From f88acd39da2a509081e541b84ecbf204ef20f9e8 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Thu, 19 Dec 2013 13:36:10 +0000 Subject: Fix x86/x86_64 expm1 inaccuracy near 0 in directed rounding modes (bug 16293). Bug 16293 is inaccuracy of x86/x86_64 versions of expm1, near 0 in directed rounding modes, that arises from frndint rounding the exponent to 1 or -1 instead of 0, resulting in large cancellation error. This inaccuracy in turn affects other functions such as sinh that use expm1. This patch fixes the problem by setting round-to-nearest mode temporarily around the affected calls to frndint. I don't think this is needed for other uses of frndint, such as in exp itself, as only for expm1 is the cancellation error significant. Tested x86_64 and x86 and ulps updated accordingly. * sysdeps/i386/fpu/e_expl.S (IEEE754_EXPL) [USE_AS_EXPM1L]: Set round-to-nearest mode when using frndint. * sysdeps/i386/fpu/s_expm1.S (__expm1): Likewise. * sysdeps/i386/fpu/s_expm1f.S (__expm1f): Likewise. * sysdeps/x86_64/fpu/e_expl.S (IEEE754_EXPL) [USE_AS_EXPM1L]: Likewise. * math/auto-libm-test-in: Add more tests of expm1. Do not expect sinh test to fail. * math/auto-libm-test-out: Regenerated. * math/libm-test.inc (TEST_COND_x86_64): Remove macro. (TEST_COND_x86): Likewise. (expm1_tonearest_test_data): New array. (expm1_test_tonearest): New function. (expm1_towardzero_test_data): New array. (expm1_test_towardzero): New function. (expm1_downward_test_data): New array. (expm1_test_downward): New function. (expm1_upward_test_data): New array. (expm1_test_upward): New function. (main): Run the new test functions. * sysdeps/i386/fpu/libm-test-ulps: Update. * sysdeps/x86_64/fpu/libm-test-ulps: Likewise. --- math/auto-libm-test-in | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'math/auto-libm-test-in') diff --git a/math/auto-libm-test-in b/math/auto-libm-test-in index 50e0e6b628..28e9d455b6 100644 --- a/math/auto-libm-test-in +++ b/math/auto-libm-test-in @@ -281,6 +281,22 @@ expm1 -100000.0 expm1 100000.0 expm1 max expm1 -max +expm1 0x1p-2 +expm1 -0x1p-2 +expm1 0x1p-10 +expm1 -0x1p-10 +expm1 0x1p-20 +expm1 -0x1p-20 +expm1 0x1p-29 +expm1 -0x1p-29 +expm1 0x1p-32 +expm1 -0x1p-32 +expm1 0x1p-50 +expm1 -0x1p-50 +expm1 0x1p-64 +expm1 -0x1p-64 +expm1 0x1p-100 +expm1 -0x1p-100 hypot 0 0 hypot 0 -0 @@ -835,8 +851,7 @@ sin 10 sinh 0 sinh -0 sinh 0.75 -# Bug 16293: expm1 inaccurate in directed rounding modes. -sinh 0x8p-32 xfail:x86_64:ldbl-96-intel xfail:x86 +sinh 0x8p-32 sinh 22 sinh 23 sinh 24 -- cgit 1.4.1