diff options
author | Joseph Myers <joseph@codesourcery.com> | 2014-03-27 18:41:14 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2014-03-27 18:41:14 +0000 |
commit | 03a7091fa2afc84e215fc99fceca52baa4b0f8f1 (patch) | |
tree | c7be03c2bfe3c2509ed74f3cb8581ab1d08e5dab /sysdeps | |
parent | dd3022d75e6fb8957843d6d84257a5d8457822d5 (diff) | |
download | glibc-03a7091fa2afc84e215fc99fceca52baa4b0f8f1.tar.gz glibc-03a7091fa2afc84e215fc99fceca52baa4b0f8f1.tar.xz glibc-03a7091fa2afc84e215fc99fceca52baa4b0f8f1.zip |
Fix x86/x86_64 expl/exp10l spurious underflows (bug 16348).
This patch fixes bug 16348, spurious underflows from x86/x86_64 expl on arguments close to 0. These implementations effectively use expm1 (on the fractional part of the argument) internally, so resulting in spurious underflows when the result is very close to 1. For arguments small enough that the round-to-nearest correct result is 1, this patch uses 1+x instead. These implementations are also used for exp10l and so the patch fixes similar issues there (the 0x1p-67 threshold being small enough to be correct for exp10l as well as expl). But because of spurious underflows in other exp10 implementations (bug 16560), the tests aren't added for exp10 at this point - they can be added when the other exp10 parts of that bug are fixed. Tested x86_64 and x86; no ulps updates needed. [BZ #16348] * sysdeps/i386/fpu/e_expl.S (IEEE754_EXPL) [!USE_AS_EXPM1L]: Use 1+x for argument with exponent below -67. * sysdeps/x86_64/fpu/e_expl.S (IEEE754_EXPL) [!USE_AS_EXPM1L]: Likewise. * math/auto-libm-test-in: Add more tests of exp. * math/auto-libm-test-out: Regenerated.
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/i386/fpu/e_expl.S | 10 | ||||
-rw-r--r-- | sysdeps/x86_64/fpu/e_expl.S | 10 |
2 files changed, 16 insertions, 4 deletions
diff --git a/sysdeps/i386/fpu/e_expl.S b/sysdeps/i386/fpu/e_expl.S index 5917f574b1..eb4086b3f5 100644 --- a/sysdeps/i386/fpu/e_expl.S +++ b/sysdeps/i386/fpu/e_expl.S @@ -112,8 +112,14 @@ ENTRY(IEEE754_EXPL) movzwl 4+8(%esp), %eax andl $0x7fff, %eax cmpl $0x400d, %eax - jle 3f - /* Overflow, underflow or infinity or NaN as argument. */ + jg 5f + cmpl $0x3fbc, %eax + jge 3f + /* Argument's exponent below -67, result rounds to 1. */ + fld1 + faddp + jmp 2f +5: /* Overflow, underflow or infinity or NaN as argument. */ fstsw %ax movb $0x45, %dh andb %ah, %dh diff --git a/sysdeps/x86_64/fpu/e_expl.S b/sysdeps/x86_64/fpu/e_expl.S index 36d30c26d3..338527b3de 100644 --- a/sysdeps/x86_64/fpu/e_expl.S +++ b/sysdeps/x86_64/fpu/e_expl.S @@ -109,8 +109,14 @@ ENTRY(IEEE754_EXPL) movzwl 8+8(%rsp), %eax andl $0x7fff, %eax cmpl $0x400d, %eax - jle 3f - /* Overflow, underflow or infinity or NaN as argument. */ + jg 5f + cmpl $0x3fbc, %eax + jge 3f + /* Argument's exponent below -67, result rounds to 1. */ + fld1 + faddp + jmp 2f +5: /* Overflow, underflow or infinity or NaN as argument. */ fstsw %ax movb $0x45, %dh andb %ah, %dh |