Skip to content

Commit

Permalink
Fix tan missing underflows (bug 16517).
Browse files Browse the repository at this point in the history
Similar to various other bugs in this area, some tan 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.

Tested for x86_64, x86, mips64 and powerpc.

	[BZ #16517]
	* sysdeps/ieee754/dbl-64/s_tan.c: Include <float.h>.
	(tan): Force underflow exception for arguments with small absolute
	value.
	* sysdeps/ieee754/flt-32/k_tanf.c: Include <float.h>.
	(__kernel_tanf): Force underflow exception for arguments with
	small absolute value.
	* sysdeps/ieee754/ldbl-128/k_tanl.c: Include <float.h>.
	(__kernel_tanl): Force underflow exception for arguments with
	small absolute value.
	* sysdeps/ieee754/ldbl-128ibm/k_tanl.c: Include <float.h>.
	(__kernel_tanl): Force underflow exception for arguments with
	small absolute value.
	* sysdeps/ieee754/ldbl-96/k_tanl.c: Include <float.h>.
	(__kernel_tanl): Force underflow exception for arguments with
	small absolute value.
	* math/auto-libm-test-in: Add more tests of tan.
	* math/auto-libm-test-out: Regenerated.
  • Loading branch information
Joseph Myers committed Aug 7, 2015
1 parent db2bcbc commit 37550cb
Show file tree
Hide file tree
Showing 9 changed files with 393 additions and 5 deletions.
21 changes: 21 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
2015-08-07 Joseph Myers <joseph@codesourcery.com>

[BZ #16517]
* sysdeps/ieee754/dbl-64/s_tan.c: Include <float.h>.
(tan): Force underflow exception for arguments with small absolute
value.
* sysdeps/ieee754/flt-32/k_tanf.c: Include <float.h>.
(__kernel_tanf): Force underflow exception for arguments with
small absolute value.
* sysdeps/ieee754/ldbl-128/k_tanl.c: Include <float.h>.
(__kernel_tanl): Force underflow exception for arguments with
small absolute value.
* sysdeps/ieee754/ldbl-128ibm/k_tanl.c: Include <float.h>.
(__kernel_tanl): Force underflow exception for arguments with
small absolute value.
* sysdeps/ieee754/ldbl-96/k_tanl.c: Include <float.h>.
(__kernel_tanl): Force underflow exception for arguments with
small absolute value.
* math/auto-libm-test-in: Add more tests of tan.
* math/auto-libm-test-out: Regenerated.

2015-08-07 Samuel Thibault <samuel.thibault@ens-lyon.org>

Fix sysdeps/i386/fpu/s_scalbn.S build
Expand Down
2 changes: 1 addition & 1 deletion NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ using `glibc' in the "product" field.
Version 2.23

* The following bugs are resolved with this release:
16519, 18265, 18525, 18618, 18647, 18661.
16517, 16519, 18265, 18525, 18618, 18647, 18661.

Version 2.22

Expand Down
4 changes: 4 additions & 0 deletions math/auto-libm-test-in
Original file line number Diff line number Diff line change
Expand Up @@ -2659,6 +2659,10 @@ tan 9
tan 10
tan -0x1.062a48p+0
tan -0x1.4f69cp+0
tan min
tan -min
tan min_subnorm
tan -min_subnorm

tanh 0
tanh -0
Expand Down
316 changes: 316 additions & 0 deletions math/auto-libm-test-out

Large diffs are not rendered by default.

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

#include <errno.h>
#include <float.h>
#include "endian.h"
#include <dla.h>
#include "mpa.h"
Expand Down Expand Up @@ -91,6 +92,11 @@ tan (double x)
/* (I) The case abs(x) <= 1.259e-8 */
if (w <= g1.d)
{
if (w < DBL_MIN)
{
double force_underflow = x * x;
math_force_eval (force_underflow);
}
retval = x;
goto ret;
}
Expand Down
13 changes: 12 additions & 1 deletion sysdeps/ieee754/flt-32/k_tanf.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
static char rcsid[] = "$NetBSD: k_tanf.c,v 1.4 1995/05/10 20:46:39 jtc Exp $";
#endif

#include <float.h>
#include <math.h>
#include <math_private.h>
static const float
Expand Down Expand Up @@ -48,7 +49,17 @@ float __kernel_tanf(float x, float y, int iy)
if(ix<0x39000000) /* x < 2**-13 */
{if((int)x==0) { /* generate inexact */
if((ix|(iy+1))==0) return one/fabsf(x);
else return (iy==1)? x: -one/x;
else if (iy == 1)
{
if (fabsf (x) < FLT_MIN)
{
float force_underflow = x * x;
math_force_eval (force_underflow);
}
return x;
}
else
return -one / x;
}
}
if(ix>=0x3f2ca140) { /* |x|>=0.6744 */
Expand Down
12 changes: 11 additions & 1 deletion sysdeps/ieee754/ldbl-128/k_tanl.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
* = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y)))
*/

#include <float.h>
#include <libc-internal.h>
#include <math.h>
#include <math_private.h>
Expand Down Expand Up @@ -98,8 +99,17 @@ __kernel_tanl (long double x, long double y, int iy)
if ((ix | u.parts32.w1 | u.parts32.w2 | u.parts32.w3
| (iy + 1)) == 0)
return one / fabs (x);
else if (iy == 1)
{
if (fabsl (x) < LDBL_MIN)
{
long double force_underflow = x * x;
math_force_eval (force_underflow);
}
return x;
}
else
return (iy == 1) ? x : -one / x;
return -one / x;
}
}
if (ix >= 0x3ffe5942) /* |x| >= 0.6743316650390625 */
Expand Down
12 changes: 11 additions & 1 deletion sysdeps/ieee754/ldbl-128ibm/k_tanl.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
* = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y)))
*/

#include <float.h>
#include <libc-internal.h>
#include <math.h>
#include <math_private.h>
Expand Down Expand Up @@ -98,8 +99,17 @@ __kernel_tanl (long double x, long double y, int iy)
{
if ((ix | lx | (iy + 1)) == 0)
return one / fabs (x);
else if (iy == 1)
{
if (fabsl (x) < LDBL_MIN)
{
long double force_underflow = x * x;
math_force_eval (force_underflow);
}
return x;
}
else
return (iy == 1) ? x : -one / x;
return -one / x;
}
}
if (ix >= 0x3fe59420) /* |x| >= 0.6743316650390625 */
Expand Down
12 changes: 11 additions & 1 deletion sysdeps/ieee754/ldbl-96/k_tanl.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
* = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y)))
*/

#include <float.h>
#include <math.h>
#include <math_private.h>
static const long double
Expand Down Expand Up @@ -94,8 +95,17 @@ __kernel_tanl (long double x, long double y, int iy)
{ /* generate inexact */
if (x == 0 && iy == -1)
return one / fabsl (x);
else if (iy == 1)
{
if (absx < LDBL_MIN)
{
long double force_underflow = x * x;
math_force_eval (force_underflow);
}
return x;
}
else
return (iy == 1) ? x : -one / x;
return -one / x;
}
}
if (absx >= 0.6743316650390625L)
Expand Down

0 comments on commit 37550cb

Please sign in to comment.