diff options
author | Joseph Myers <joseph@codesourcery.com> | 2016-03-24 01:32:52 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2016-03-24 01:32:52 +0000 |
commit | c898991d8bcfacc825097ba389ffccc5367c2b2d (patch) | |
tree | ef1f3fec885e5e5ed89048016ffe8b8b2c0e8393 /sysdeps | |
parent | 7e1ff08c260ae105208edb4e778e50525dff05d3 (diff) | |
download | glibc-c898991d8bcfacc825097ba389ffccc5367c2b2d.tar glibc-c898991d8bcfacc825097ba389ffccc5367c2b2d.tar.gz glibc-c898991d8bcfacc825097ba389ffccc5367c2b2d.tar.bz2 glibc-c898991d8bcfacc825097ba389ffccc5367c2b2d.zip |
Fix x86_64 / x86 powl inaccuracy for integer exponents (bug 19848).
Bug 19848 reports cases where powl on x86 / x86_64 has error
accumulation, for small integer exponents, larger than permitted by
glibc's accuracy goals, at least in some rounding modes. This patch
further restricts the exponent range for which the
small-integer-exponent logic is used to limit the possible error
accumulation.
Tested for x86_64 and x86 and ulps updated accordingly.
[BZ #19848]
* sysdeps/i386/fpu/e_powl.S (p3): Rename to p2 and change value
from 8 to 4.
(__ieee754_powl): Compare integer exponent against 4 not 8.
* sysdeps/x86_64/fpu/e_powl.S (p3): Rename to p2 and change value
from 8 to 4.
(__ieee754_powl): Compare integer exponent against 4 not 8.
* math/auto-libm-test-in: Add more tests of pow.
* math/auto-libm-test-out: Regenerated.
* sysdeps/i386/i686/fpu/multiarch/libm-test-ulps: Update.
* sysdeps/x86_64/fpu/libm-test-ulps: Likewise.
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/i386/fpu/e_powl.S | 10 | ||||
-rw-r--r-- | sysdeps/i386/i686/fpu/multiarch/libm-test-ulps | 8 | ||||
-rw-r--r-- | sysdeps/x86_64/fpu/e_powl.S | 16 | ||||
-rw-r--r-- | sysdeps/x86_64/fpu/libm-test-ulps | 8 |
4 files changed, 21 insertions, 21 deletions
diff --git a/sysdeps/i386/fpu/e_powl.S b/sysdeps/i386/fpu/e_powl.S index 77d2abfaea..923ee37222 100644 --- a/sysdeps/i386/fpu/e_powl.S +++ b/sysdeps/i386/fpu/e_powl.S @@ -26,9 +26,9 @@ .type one,@object one: .double 1.0 ASM_SIZE_DIRECTIVE(one) - .type p3,@object -p3: .byte 0, 0, 0, 0, 0, 0, 0x20, 0x40 - ASM_SIZE_DIRECTIVE(p3) + .type p2,@object +p2: .byte 0, 0, 0, 0, 0, 0, 0x10, 0x40 + ASM_SIZE_DIRECTIVE(p2) .type p63,@object p63: .byte 0, 0, 0, 0, 0, 0, 0xe0, 0x43 ASM_SIZE_DIRECTIVE(p63) @@ -146,11 +146,11 @@ ENTRY(__ieee754_powl) jmp 3f 9: /* OK, we have an integer value for y. Unless very small - (we use < 8), use the algorithm for real exponent to avoid + (we use < 4), use the algorithm for real exponent to avoid accumulation of errors. */ fld %st // y : y : x fabs // |y| : y : x - fcompl MO(p3) // y : x + fcompl MO(p2) // y : x fnstsw sahf jnc 3f diff --git a/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps b/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps index bbb644a591..585be7880d 100644 --- a/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps +++ b/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps @@ -1903,14 +1903,14 @@ ldouble: 4 Function: "pow_towardzero": double: 1 idouble: 1 -ildouble: 1 -ldouble: 1 +ildouble: 4 +ldouble: 4 Function: "pow_upward": double: 1 idouble: 1 -ildouble: 2 -ldouble: 2 +ildouble: 4 +ldouble: 4 Function: "sin": ildouble: 1 diff --git a/sysdeps/x86_64/fpu/e_powl.S b/sysdeps/x86_64/fpu/e_powl.S index 1f68cf0102..4a7f3a18d3 100644 --- a/sysdeps/x86_64/fpu/e_powl.S +++ b/sysdeps/x86_64/fpu/e_powl.S @@ -26,9 +26,9 @@ .type one,@object one: .double 1.0 ASM_SIZE_DIRECTIVE(one) - .type p3,@object -p3: .byte 0, 0, 0, 0, 0, 0, 0x20, 0x40 - ASM_SIZE_DIRECTIVE(p3) + .type p2,@object +p2: .byte 0, 0, 0, 0, 0, 0, 0x10, 0x40 + ASM_SIZE_DIRECTIVE(p2) .type p63,@object p63: .byte 0, 0, 0, 0, 0, 0, 0xe0, 0x43 ASM_SIZE_DIRECTIVE(p63) @@ -136,12 +136,12 @@ ENTRY(__ieee754_powl) jmp 3f 9: /* OK, we have an integer value for y. Unless very small - (we use < 8), use the algorithm for real exponent to avoid + (we use < 4), use the algorithm for real exponent to avoid accumulation of errors. */ - fldl MO(p3) // 8 : y : x - fld %st(1) // y : 8 : y : x - fabs // |y| : 8 : y : x - fcomip %st(1), %st // 8 : y : x + fldl MO(p2) // 4 : y : x + fld %st(1) // y : 4 : y : x + fabs // |y| : 4 : y : x + fcomip %st(1), %st // 4 : y : x fstp %st(0) // y : x jnc 3f mov -8(%rsp),%eax diff --git a/sysdeps/x86_64/fpu/libm-test-ulps b/sysdeps/x86_64/fpu/libm-test-ulps index 445b47527d..7e7707bda0 100644 --- a/sysdeps/x86_64/fpu/libm-test-ulps +++ b/sysdeps/x86_64/fpu/libm-test-ulps @@ -2016,16 +2016,16 @@ double: 1 float: 1 idouble: 1 ifloat: 1 -ildouble: 1 -ldouble: 1 +ildouble: 4 +ldouble: 4 Function: "pow_upward": double: 1 float: 1 idouble: 1 ifloat: 1 -ildouble: 2 -ldouble: 2 +ildouble: 4 +ldouble: 4 Function: "pow_vlen16": float: 3 |