Skip to content

Commit

Permalink
Fix atanhl missing underflows (bug 16352).
Browse files Browse the repository at this point in the history
Similar to various other bugs in this area, some atanh implementations
do not raise the underflow exception for subnormal arguments, when the
result is tiny and inexact.  This patch forces the exception in a
similar way to previous fixes.  (No change in this regard is needed
for the i386 implementation; special handling to force underflows in
these cases will only be needed there when the spurious underflows,
bug 18049, get fixed.)

Tested for x86_64, x86, powerpc and mips64.

	[BZ #16352]
	* sysdeps/i386/fpu/e_atanh.S (dbl_min): New object.
	(__ieee754_atanh): Force underflow exception for results with
	small absolute value.
	* sysdeps/i386/fpu/e_atanhf.S (flt_min): New object.
	(__ieee754_atanhf): Force underflow exception for results with
	small absolute value.
	* sysdeps/ieee754/dbl-64/e_atanh.c: Include <float.h>.
	(__ieee754_atanh): Force underflow exception for results with
	small absolute value.
	* sysdeps/ieee754/flt-32/e_atanhf.c: Include <float.h>.
	(__ieee754_atanhf): Force underflow exception for results with
	small absolute value.
	* sysdeps/ieee754/ldbl-128/e_atanhl.c: Include <float.h>.
	(__ieee754_atanhl): Force underflow exception for results with
	small absolute value.
	* sysdeps/ieee754/ldbl-128ibm/e_atanhl.c: Include <float.h>.
	(__ieee754_atanhl): Force underflow exception for results with
	small absolute value.
	* sysdeps/ieee754/ldbl-96/e_atanhl.c: Include <float.h>.
	(__ieee754_atanhl): Force underflow exception for results with
	small absolute value.
	* math/auto-libm-test-in: Do not allow missing underflow
	exceptions from atanh.
	* math/auto-libm-test-out: Regenerated.
  • Loading branch information
Joseph Myers committed May 15, 2015
1 parent 5a608cc commit 8020a80
Show file tree
Hide file tree
Showing 11 changed files with 235 additions and 137 deletions.
26 changes: 26 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,5 +1,31 @@
2015-05-15 Joseph Myers <joseph@codesourcery.com>

[BZ #16352]
* sysdeps/i386/fpu/e_atanh.S (dbl_min): New object.
(__ieee754_atanh): Force underflow exception for results with
small absolute value.
* sysdeps/i386/fpu/e_atanhf.S (flt_min): New object.
(__ieee754_atanhf): Force underflow exception for results with
small absolute value.
* sysdeps/ieee754/dbl-64/e_atanh.c: Include <float.h>.
(__ieee754_atanh): Force underflow exception for results with
small absolute value.
* sysdeps/ieee754/flt-32/e_atanhf.c: Include <float.h>.
(__ieee754_atanhf): Force underflow exception for results with
small absolute value.
* sysdeps/ieee754/ldbl-128/e_atanhl.c: Include <float.h>.
(__ieee754_atanhl): Force underflow exception for results with
small absolute value.
* sysdeps/ieee754/ldbl-128ibm/e_atanhl.c: Include <float.h>.
(__ieee754_atanhl): Force underflow exception for results with
small absolute value.
* sysdeps/ieee754/ldbl-96/e_atanhl.c: Include <float.h>.
(__ieee754_atanhl): Force underflow exception for results with
small absolute value.
* math/auto-libm-test-in: Do not allow missing underflow
exceptions from atanh.
* math/auto-libm-test-out: Regenerated.

[BZ #18221]
* sysdeps/ieee754/flt-32/k_tanf.c (__kernel_tanf): Use 2**-13 not
2**-28 as threshold for returning x or +/- 1/x.
Expand Down
17 changes: 9 additions & 8 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ Version 2.22
* The following bugs are resolved with this release:

4719, 6792, 13064, 14094, 14841, 14906, 15319, 15467, 15790, 15969, 16339,
16351, 16512, 16560, 16704, 16783, 16850, 17090, 17195, 17269, 17523,
17542, 17569, 17588, 17596, 17620, 17621, 17628, 17631, 17692, 17711,
17715, 17776, 17779, 17792, 17836, 17912, 17916, 17930, 17932, 17944,
17949, 17964, 17965, 17967, 17969, 17978, 17987, 17991, 17996, 17998,
17999, 18007, 18019, 18020, 18029, 18030, 18032, 18036, 18038, 18039,
18042, 18043, 18046, 18047, 18068, 18080, 18093, 18100, 18104, 18110,
18111, 18125, 18128, 18138, 18185, 18196, 18197, 18206, 18210, 18211,
18217, 18220, 18221, 18247, 18287, 18319, 18333, 18346, 18397, 18409.
16351, 16352, 16512, 16560, 16704, 16783, 16850, 17090, 17195, 17269,
17523, 17542, 17569, 17588, 17596, 17620, 17621, 17628, 17631, 17692,
17711, 17715, 17776, 17779, 17792, 17836, 17912, 17916, 17930, 17932,
17944, 17949, 17964, 17965, 17967, 17969, 17978, 17987, 17991, 17996,
17998, 17999, 18007, 18019, 18020, 18029, 18030, 18032, 18036, 18038,
18039, 18042, 18043, 18046, 18047, 18068, 18080, 18093, 18100, 18104,
18110, 18111, 18125, 18128, 18138, 18185, 18196, 18197, 18206, 18210,
18211, 18217, 18220, 18221, 18247, 18287, 18319, 18333, 18346, 18397,
18409.

* Cache information can be queried via sysconf() function on s390 e.g. with
_SC_LEVEL1_ICACHE_SIZE as argument.
Expand Down
13 changes: 6 additions & 7 deletions math/auto-libm-test-in
Original file line number Diff line number Diff line change
Expand Up @@ -382,13 +382,12 @@ atanh 0x3.91d9f3c80c72d7acp-4
atanh -0x2.6c52c26567198p-4
atanh 0x3.a274ecp-4
atanh -0x3.f0f519a687b64p-8
# Bug 16352: underflow exception may be missing.
atanh 0x1p-500 missing-underflow
atanh 0x1p-5000 missing-underflow
atanh min missing-underflow
atanh -min missing-underflow
atanh min_subnorm missing-underflow
atanh -min_subnorm missing-underflow
atanh 0x1p-500
atanh 0x1p-5000
atanh min
atanh -min
atanh min_subnorm
atanh -min_subnorm

# cabs (x,y) == cabs (y,x).
cabs 0.75 12.390625
Expand Down
236 changes: 118 additions & 118 deletions math/auto-libm-test-out

Large diffs are not rendered by default.

20 changes: 19 additions & 1 deletion sysdeps/i386/fpu/e_atanh.S
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ limit: .double 0.29
ln2_2: .tfloat 0.3465735902799726547086160
ASM_SIZE_DIRECTIVE(ln2_2)

.section .rodata.cst8,"aM",@progbits,8

.p2align 3
.type dbl_min,@object
dbl_min: .byte 0, 0, 0, 0, 0, 0, 0x10, 0
ASM_SIZE_DIRECTIVE(dbl_min)

#ifdef PIC
#define MO(op) op##@GOTOFF(%edx)
#else
Expand Down Expand Up @@ -81,7 +88,18 @@ ENTRY(__ieee754_atanh)
sahf
jae 4f
fyl2xp1 // 0.5*ln2*ld(1+2*|x|+(2*|x|^2)/(1-|x|))
jecxz 3f
fcoml MO(dbl_min)
fnstsw
sahf
jae 8f
subl $8, %esp
cfi_adjust_cfa_offset (8)
fld %st(0)
fmul %st(0)
fstpl (%esp)
addl $8, %esp
cfi_adjust_cfa_offset (-8)
8: jecxz 3f
fchs // 0.5*ln2*ld(1+2*x+(2*x^2)/(1-x))
3: ret

Expand Down
20 changes: 19 additions & 1 deletion sysdeps/i386/fpu/e_atanhf.S
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ limit: .double 0.29
ln2_2: .tfloat 0.3465735902799726547086160
ASM_SIZE_DIRECTIVE(ln2_2)

.section .rodata.cst4,"aM",@progbits,4

.p2align 2
.type flt_min,@object
flt_min: .byte 0, 0, 0x80, 0
ASM_SIZE_DIRECTIVE(flt_min)

#ifdef PIC
#define MO(op) op##@GOTOFF(%edx)
#else
Expand Down Expand Up @@ -77,7 +84,18 @@ ENTRY(__ieee754_atanhf)
sahf
jae 4f
fyl2xp1 // 0.5*ln2*ld(1+2*|x|+(2*|x|^2)/(1-|x|))
jecxz 3f
fcoms MO(flt_min)
fnstsw
sahf
jae 6f
subl $4, %esp
cfi_adjust_cfa_offset (4)
fld %st(0)
fmul %st(0)
fstps (%esp)
addl $4, %esp
cfi_adjust_cfa_offset (-4)
6: jecxz 3f
fchs // 0.5*ln2*ld(1+2*x+(2*x^2)/(1-x))
3: ret

Expand Down
6 changes: 6 additions & 0 deletions sysdeps/ieee754/dbl-64/e_atanh.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
*/

#include <float.h>
#include <inttypes.h>
#include <math.h>
#include <math_private.h>
Expand All @@ -51,6 +52,11 @@ __ieee754_atanh (double x)
if (__glibc_unlikely (xa < 0x1.0p-28))
{
math_force_eval (huge + x);
if (fabs (x) < DBL_MIN)
{
double force_underflow = x * x;
math_force_eval (force_underflow);
}
return x;
}

Expand Down
6 changes: 6 additions & 0 deletions sysdeps/ieee754/flt-32/e_atanhf.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
*/

#include <float.h>
#include <inttypes.h>
#include <math.h>
#include <math_private.h>
Expand All @@ -51,6 +52,11 @@ __ieee754_atanhf (float x)
if (__glibc_unlikely (xa < 0x1.0p-28f))
{
math_force_eval (huge + x);
if (fabsf (x) < FLT_MIN)
{
float force_underflow = x * x;
math_force_eval (force_underflow);
}
return x;
}

Expand Down
11 changes: 10 additions & 1 deletion sysdeps/ieee754/ldbl-128/e_atanhl.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
*
*/

#include <float.h>
#include <math.h>
#include <math_private.h>

Expand All @@ -57,7 +58,15 @@ __ieee754_atanhl(long double x)
else
return (x-x)/(x-x);
}
if(ix<0x3fc60000 && (huge+x)>zero) return x; /* x < 2^-57 */
if(ix<0x3fc60000 && (huge+x)>zero) /* x < 2^-57 */
{
if (fabsl (x) < LDBL_MIN)
{
long double force_underflow = x * x;
math_force_eval (force_underflow);
}
return x;
}

if(ix<0x3ffe0000) { /* x < 0.5 */
t = u.value+u.value;
Expand Down
11 changes: 10 additions & 1 deletion sysdeps/ieee754/ldbl-128ibm/e_atanhl.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
*
*/

#include <float.h>
#include <math.h>
#include <math_private.h>

Expand All @@ -54,7 +55,15 @@ __ieee754_atanhl(long double x)
if (t == one)
return x/zero;
}
if(ix<0x3c70000000000000LL&&(huge+x)>zero) return x; /* x<2**-56 */
if(ix<0x3c70000000000000LL&&(huge+x)>zero) /* x<2**-56 */
{
if (fabsl (x) < LDBL_MIN)
{
long double force_underflow = x * x;
math_force_eval (force_underflow);
}
return x;
}
x = fabsl (x);
if(ix<0x3fe0000000000000LL) { /* x < 0.5 */
t = x+x;
Expand Down
6 changes: 6 additions & 0 deletions sysdeps/ieee754/ldbl-96/e_atanhl.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
*
*/

#include <float.h>
#include <math.h>
#include <math_private.h>

Expand All @@ -54,6 +55,11 @@ __ieee754_atanhl(long double x)
return x/zero;
if(ix<0x3fdf) {
math_force_eval(huge+x);
if (fabsl (x) < LDBL_MIN)
{
long double force_underflow = x * x;
math_force_eval (force_underflow);
}
return x; /* x<2**-32 */
}
SET_LDOUBLE_EXP(x,ix);
Expand Down

0 comments on commit 8020a80

Please sign in to comment.