Fix x86/x86_64 expm1l spurious underflow exceptions (bug 16539).

This patch fixes bug 16539, spurious underflow exceptions from x86 /
x86-64 expm1l.  The problem is that the computation of a base-2
exponent with extra precision involves spurious underflows for
arguments that are small but not subnormal, so a check is added to
just return the argument in those cases.  (If the argument *is*
subnormal, underflowing is correct and the existing code will always
underflow, so it suffices to keep using the existing code in that
case; some expm1 implementations have a bug (bug 16353) with missing
underflow exceptions, but I don't think there's such a bug in this
particular version.)

Tested x86_64 and x86; no ulps updates needed.

(auto-libm-test-out diffs omitted below.)

	[BZ #16539]
	* sysdeps/i386/fpu/e_expl.S (IEEE754_EXPL) [USE_AS_EXPM1L]: Just
	return the argument for normal arguments with exponent below -64.
	* sysdeps/x86_64/fpu/e_expl.S (IEEE754_EXPL) [USE_AS_EXPM1L]:
	Likewise.
	* math/auto-libm-test-in: Add another test of expm1.
	* math/auto-libm-test-out: Regenerated.
This commit is contained in:
Joseph Myers 2014-06-24 21:00:08 +00:00
parent e7dd3c8c1d
commit 4060283dec
6 changed files with 122 additions and 11 deletions

View File

@ -1,5 +1,13 @@
2014-06-24 Joseph Myers <joseph@codesourcery.com>
[BZ #16539]
* sysdeps/i386/fpu/e_expl.S (IEEE754_EXPL) [USE_AS_EXPM1L]: Just
return the argument for normal arguments with exponent below -64.
* sysdeps/x86_64/fpu/e_expl.S (IEEE754_EXPL) [USE_AS_EXPM1L]:
Likewise.
* math/auto-libm-test-in: Add another test of expm1.
* math/auto-libm-test-out: Regenerated.
[BZ #16287]
* sysdeps/ieee754/ldbl-128/s_erfl.c (__erfl): Return 1 without
calling __erfcl for arguments at least 16.

22
NEWS
View File

@ -11,17 +11,17 @@ Version 2.20
6804, 9894, 12994, 13347, 13651, 14308, 14770, 15119, 15132, 15347, 15514,
15698, 15804, 15894, 15946, 16002, 16064, 16095, 16198, 16284, 16287,
16315, 16348, 16349, 16354, 16357, 16362, 16447, 16516, 16532, 16545,
16564, 16574, 16599, 16600, 16609, 16610, 16611, 16613, 16619, 16623,
16629, 16632, 16634, 16639, 16642, 16648, 16649, 16670, 16674, 16677,
16680, 16681, 16683, 16689, 16695, 16701, 16706, 16707, 16712, 16713,
16714, 16724, 16731, 16739, 16740, 16743, 16754, 16758, 16759, 16760,
16770, 16786, 16789, 16791, 16796, 16799, 16800, 16815, 16823, 16824,
16831, 16838, 16849, 16854, 16876, 16877, 16878, 16882, 16885, 16888,
16890, 16912, 16915, 16916, 16917, 16918, 16922, 16927, 16928, 16932,
16943, 16958, 16965, 16966, 16967, 16977, 16978, 16984, 16990, 16996,
17009, 17022, 17031, 17042, 17048, 17050, 17058, 17061, 17062, 17069,
17075, 17079, 17084.
16315, 16348, 16349, 16354, 16357, 16362, 16447, 16516, 16532, 16539,
16545, 16564, 16574, 16599, 16600, 16609, 16610, 16611, 16613, 16619,
16623, 16629, 16632, 16634, 16639, 16642, 16648, 16649, 16670, 16674,
16677, 16680, 16681, 16683, 16689, 16695, 16701, 16706, 16707, 16712,
16713, 16714, 16724, 16731, 16739, 16740, 16743, 16754, 16758, 16759,
16760, 16770, 16786, 16789, 16791, 16796, 16799, 16800, 16815, 16823,
16824, 16831, 16838, 16849, 16854, 16876, 16877, 16878, 16882, 16885,
16888, 16890, 16912, 16915, 16916, 16917, 16918, 16922, 16927, 16928,
16932, 16943, 16958, 16965, 16966, 16967, 16977, 16978, 16984, 16990,
16996, 17009, 17022, 17031, 17042, 17048, 17050, 17058, 17061, 17062,
17069, 17075, 17079, 17084.
* Optimized strchr implementation for AArch64. Contributed by ARM Ltd.

View File

@ -970,6 +970,8 @@ expm1 0x1p-64
expm1 -0x1p-64
expm1 0x1p-100
expm1 -0x1p-100
# Bug 16353: underflow exception may be missing
expm1 0x4.0000000000000028p-16384 missing-underflow
fma 1.0 2.0 3.0
fma 1.25 0.75 0.0625

View File

@ -93045,6 +93045,87 @@ expm1 -0x1p-100
= expm1 tonearest ldbl-128ibm -0x1p-100L : -0xf.ffffffffffffffffffffffff8p-104L : inexact-ok
= expm1 towardzero ldbl-128ibm -0x1p-100L : -0xf.ffffffffffffffffffffffff8p-104L : inexact-ok
= expm1 upward ldbl-128ibm -0x1p-100L : -0xf.ffffffffffffffffffffffff8p-104L : inexact-ok
expm1 0x4.0000000000000028p-16384 missing-underflow
= expm1 downward flt-32 0x8p-152f : 0x8p-152f : inexact-ok underflow underflow-ok errno-erange-ok
= expm1 tonearest flt-32 0x8p-152f : 0x8p-152f : inexact-ok underflow underflow-ok errno-erange-ok
= expm1 towardzero flt-32 0x8p-152f : 0x8p-152f : inexact-ok underflow underflow-ok errno-erange-ok
= expm1 upward flt-32 0x8p-152f : 0x1p-148f : inexact-ok underflow underflow-ok errno-erange-ok
= expm1 downward dbl-64 0x8p-152 : 0x8p-152 : inexact-ok
= expm1 tonearest dbl-64 0x8p-152 : 0x8p-152 : inexact-ok
= expm1 towardzero dbl-64 0x8p-152 : 0x8p-152 : inexact-ok
= expm1 upward dbl-64 0x8p-152 : 0x8.0000000000008p-152 : inexact-ok
= expm1 downward ldbl-96-intel 0x8p-152L : 0x8p-152L : inexact-ok
= expm1 tonearest ldbl-96-intel 0x8p-152L : 0x8p-152L : inexact-ok
= expm1 towardzero ldbl-96-intel 0x8p-152L : 0x8p-152L : inexact-ok
= expm1 upward ldbl-96-intel 0x8p-152L : 0x8.000000000000001p-152L : inexact-ok
= expm1 downward ldbl-96-m68k 0x8p-152L : 0x8p-152L : inexact-ok
= expm1 tonearest ldbl-96-m68k 0x8p-152L : 0x8p-152L : inexact-ok
= expm1 towardzero ldbl-96-m68k 0x8p-152L : 0x8p-152L : inexact-ok
= expm1 upward ldbl-96-m68k 0x8p-152L : 0x8.000000000000001p-152L : inexact-ok
= expm1 downward ldbl-128 0x8p-152L : 0x8p-152L : inexact-ok
= expm1 tonearest ldbl-128 0x8p-152L : 0x8p-152L : inexact-ok
= expm1 towardzero ldbl-128 0x8p-152L : 0x8p-152L : inexact-ok
= expm1 upward ldbl-128 0x8p-152L : 0x8.0000000000000000000000000008p-152L : inexact-ok
= expm1 downward ldbl-128ibm 0x8p-152L : 0x8p-152L : inexact-ok
= expm1 tonearest ldbl-128ibm 0x8p-152L : 0x8p-152L : inexact-ok
= expm1 towardzero ldbl-128ibm 0x8p-152L : 0x8p-152L : inexact-ok
= expm1 upward ldbl-128ibm 0x8p-152L : 0x8.00000000000000000000000004p-152L : inexact-ok
= expm1 downward flt-32 0x0p+0f : 0x0p+0f : inexact-ok
= expm1 tonearest flt-32 0x0p+0f : 0x0p+0f : inexact-ok
= expm1 towardzero flt-32 0x0p+0f : 0x0p+0f : inexact-ok
= expm1 upward flt-32 0x0p+0f : 0x0p+0f : inexact-ok
= expm1 downward dbl-64 0x0p+0 : 0x0p+0 : inexact-ok
= expm1 tonearest dbl-64 0x0p+0 : 0x0p+0 : inexact-ok
= expm1 towardzero dbl-64 0x0p+0 : 0x0p+0 : inexact-ok
= expm1 upward dbl-64 0x0p+0 : 0x0p+0 : inexact-ok
= expm1 downward ldbl-96-intel 0x0p+0L : 0x0p+0L : inexact-ok
= expm1 tonearest ldbl-96-intel 0x0p+0L : 0x0p+0L : inexact-ok
= expm1 towardzero ldbl-96-intel 0x0p+0L : 0x0p+0L : inexact-ok
= expm1 upward ldbl-96-intel 0x0p+0L : 0x0p+0L : inexact-ok
= expm1 downward ldbl-96-m68k 0x0p+0L : 0x0p+0L : inexact-ok
= expm1 tonearest ldbl-96-m68k 0x0p+0L : 0x0p+0L : inexact-ok
= expm1 towardzero ldbl-96-m68k 0x0p+0L : 0x0p+0L : inexact-ok
= expm1 upward ldbl-96-m68k 0x0p+0L : 0x0p+0L : inexact-ok
= expm1 downward ldbl-128 0x0p+0L : 0x0p+0L : inexact-ok
= expm1 tonearest ldbl-128 0x0p+0L : 0x0p+0L : inexact-ok
= expm1 towardzero ldbl-128 0x0p+0L : 0x0p+0L : inexact-ok
= expm1 upward ldbl-128 0x0p+0L : 0x0p+0L : inexact-ok
= expm1 downward ldbl-128ibm 0x0p+0L : 0x0p+0L : inexact-ok
= expm1 tonearest ldbl-128ibm 0x0p+0L : 0x0p+0L : inexact-ok
= expm1 towardzero ldbl-128ibm 0x0p+0L : 0x0p+0L : inexact-ok
= expm1 upward ldbl-128ibm 0x0p+0L : 0x0p+0L : inexact-ok
= expm1 downward dbl-64 0x4p-1076 : 0x4p-1076 : inexact-ok underflow underflow-ok errno-erange-ok
= expm1 tonearest dbl-64 0x4p-1076 : 0x4p-1076 : inexact-ok underflow underflow-ok errno-erange-ok
= expm1 towardzero dbl-64 0x4p-1076 : 0x4p-1076 : inexact-ok underflow underflow-ok errno-erange-ok
= expm1 upward dbl-64 0x4p-1076 : 0x8p-1076 : inexact-ok underflow underflow-ok errno-erange-ok
= expm1 downward ldbl-96-intel 0x4p-1076L : 0x4p-1076L : inexact-ok
= expm1 tonearest ldbl-96-intel 0x4p-1076L : 0x4p-1076L : inexact-ok
= expm1 towardzero ldbl-96-intel 0x4p-1076L : 0x4p-1076L : inexact-ok
= expm1 upward ldbl-96-intel 0x4p-1076L : 0x4.0000000000000008p-1076L : inexact-ok
= expm1 downward ldbl-96-m68k 0x4p-1076L : 0x4p-1076L : inexact-ok
= expm1 tonearest ldbl-96-m68k 0x4p-1076L : 0x4p-1076L : inexact-ok
= expm1 towardzero ldbl-96-m68k 0x4p-1076L : 0x4p-1076L : inexact-ok
= expm1 upward ldbl-96-m68k 0x4p-1076L : 0x4.0000000000000008p-1076L : inexact-ok
= expm1 downward ldbl-128 0x4p-1076L : 0x4p-1076L : inexact-ok
= expm1 tonearest ldbl-128 0x4p-1076L : 0x4p-1076L : inexact-ok
= expm1 towardzero ldbl-128 0x4p-1076L : 0x4p-1076L : inexact-ok
= expm1 upward ldbl-128 0x4p-1076L : 0x4.0000000000000000000000000004p-1076L : inexact-ok
= expm1 downward ldbl-128ibm 0x4p-1076L : 0x4p-1076L : inexact-ok underflow underflow-ok errno-erange-ok
= expm1 tonearest ldbl-128ibm 0x4p-1076L : 0x4p-1076L : inexact-ok underflow underflow-ok errno-erange-ok
= expm1 towardzero ldbl-128ibm 0x4p-1076L : 0x4p-1076L : inexact-ok underflow underflow-ok errno-erange-ok
= expm1 upward ldbl-128ibm 0x4p-1076L : 0x8p-1076L : inexact-ok underflow underflow-ok errno-erange-ok
= expm1 downward ldbl-96-intel 0x4.0000000000000028p-16384L : 0x4.0000000000000028p-16384L : inexact-ok
= expm1 tonearest ldbl-96-intel 0x4.0000000000000028p-16384L : 0x4.0000000000000028p-16384L : inexact-ok
= expm1 towardzero ldbl-96-intel 0x4.0000000000000028p-16384L : 0x4.0000000000000028p-16384L : inexact-ok
= expm1 upward ldbl-96-intel 0x4.0000000000000028p-16384L : 0x4.000000000000003p-16384L : inexact-ok
= expm1 downward ldbl-96-m68k 0x4.0000000000000028p-16384L : 0x4.0000000000000028p-16384L : inexact-ok
= expm1 tonearest ldbl-96-m68k 0x4.0000000000000028p-16384L : 0x4.0000000000000028p-16384L : inexact-ok
= expm1 towardzero ldbl-96-m68k 0x4.0000000000000028p-16384L : 0x4.0000000000000028p-16384L : inexact-ok
= expm1 upward ldbl-96-m68k 0x4.0000000000000028p-16384L : 0x4.000000000000003p-16384L : inexact-ok
= expm1 downward ldbl-128 0x4.0000000000000028p-16384L : 0x4.0000000000000028p-16384L : inexact-ok
= expm1 tonearest ldbl-128 0x4.0000000000000028p-16384L : 0x4.0000000000000028p-16384L : inexact-ok
= expm1 towardzero ldbl-128 0x4.0000000000000028p-16384L : 0x4.0000000000000028p-16384L : inexact-ok
= expm1 upward ldbl-128 0x4.0000000000000028p-16384L : 0x4.0000000000000028000000000004p-16384L : inexact-ok
fma 1.0 2.0 3.0
= fma downward flt-32 0x1p+0f 0x2p+0f 0x3p+0f : 0x5p+0f :
= fma tonearest flt-32 0x1p+0f 0x2p+0f 0x3p+0f : 0x5p+0f :

View File

@ -108,6 +108,16 @@ ENTRY(IEEE754_EXPL)
andb %ah, %dh
cmpb $0x40, %dh
je 2f
/* Test for arguments that are small but not subnormal. */
movzwl 4+8(%esp), %eax
andl $0x7fff, %eax
cmpl $0x3fbf, %eax
jge 3f
/* Argument's exponent below -64; avoid spurious underflow if
normal. */
cmpl $0x0001, %eax
jge 2f
#else
movzwl 4+8(%esp), %eax
andl $0x7fff, %eax

View File

@ -105,6 +105,16 @@ ENTRY(IEEE754_EXPL)
andb %ah, %dh
cmpb $0x40, %dh
je 2f
/* Test for arguments that are small but not subnormal. */
movzwl 8+8(%rsp), %eax
andl $0x7fff, %eax
cmpl $0x3fbf, %eax
jge 3f
/* Argument's exponent below -64; avoid spurious underflow if
normal. */
cmpl $0x0001, %eax
jge 2f
#else
movzwl 8+8(%rsp), %eax
andl $0x7fff, %eax