Set errno for y1 overflow (bug 17050)

Message ID Pine.LNX.4.64.1406121813220.11932@digraph.polyomino.org.uk
State Committed
Headers

Commit Message

Joseph Myers June 12, 2014, 6:14 p.m. UTC
  This patch fixes bug 17050, missing errno setting for y1 overflow (for
small positive arguments).  An appropriate check is added for overflow
directly in the __ieee754_y1 implementation, similar to the check
present for yn (doing it there rather than in the wrapper also avoids
yn needing to repeat the check when called for order 1 or -1 and it
uses __ieee754_y1).

Tested x86_64 and x86; no ulps update needed.  Also tested for mips64
to verify the ldbl-128 fix (the ldbl-128ibm code just #includes the
ldbl-128 file).

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

2014-06-12  Joseph Myers  <joseph@codesourcery.com>

	[BZ #17050]
	* sysdeps/ieee754/dbl-64/e_j1.c: Include <errno.h>.
	(__ieee754_y1): Set errno if return value overflows.
	* sysdeps/ieee754/flt-32/e_j1f.c: Include <errno.h>.
	(__ieee754_y1f): Set errno if return value overflows.
	* sysdeps/ieee754/ldbl-128/e_j1l.c: Include <errno.h>.
	(__ieee754_y1l): Set errno if return value overflows.
	* sysdeps/ieee754/ldbl-96/e_j1l.c: Include <errno.h>.
	(__ieee754_y1l): Set errno if return value overflows.
	* math/auto-libm-test-in: Add more tests of y0, y1 and yn.
	* math/auto-libm-test-out: Regenerated.
  

Comments

Joseph Myers June 18, 2014, 10:41 a.m. UTC | #1
Ping.  This patch 
<https://sourceware.org/ml/libc-alpha/2014-06/msg00322.html> is pending 
review.
  
Joseph Myers June 23, 2014, 11:55 a.m. UTC | #2
Ping^2.  This patch 
<https://sourceware.org/ml/libc-alpha/2014-06/msg00322.html> is still 
pending review.
  
Andreas Jaeger June 23, 2014, 6:24 p.m. UTC | #3
On 06/12/2014 08:14 PM, Joseph S. Myers wrote:
> This patch fixes bug 17050, missing errno setting for y1 overflow (for
> small positive arguments).  An appropriate check is added for overflow
> directly in the __ieee754_y1 implementation, similar to the check
> present for yn (doing it there rather than in the wrapper also avoids
> yn needing to repeat the check when called for order 1 or -1 and it
> uses __ieee754_y1).
> 
> Tested x86_64 and x86; no ulps update needed.  Also tested for mips64
> to verify the ldbl-128 fix (the ldbl-128ibm code just #includes the
> ldbl-128 file).

Ok, thanks,

Andreas
  

Patch

diff --git a/math/auto-libm-test-in b/math/auto-libm-test-in
index 6edad5a..ce50e39 100644
--- a/math/auto-libm-test-in
+++ b/math/auto-libm-test-in
@@ -2393,6 +2393,8 @@  y0 0x1p-80
 y0 0x1p-90
 y0 0x1p-100
 y0 0x1p-110
+y0 min
+y0 min_subnorm
 
 y1 0.125
 y1 0.75
@@ -2417,6 +2419,8 @@  y1 0x1p-80
 y1 0x1p-90
 y1 0x1p-100
 y1 0x1p-110
+y1 min
+y1 min_subnorm
 
 # yn (0, x) == y0 (x).
 yn 0 0.125
@@ -2461,3 +2465,22 @@  yn 2 0x1.ffff62p+99
 yn 2 0x1p127
 yn 2 0x1p1023
 yn 2 0x1p16383
+
+yn 0 min
+yn 0 min_subnorm
+yn 1 min
+yn 1 min_subnorm
+yn -1 min
+yn -1 min_subnorm
+yn 2 min
+yn 2 min_subnorm
+yn -2 min
+yn -2 min_subnorm
+yn 17 min
+yn 17 min_subnorm
+yn -17 min
+yn -17 min_subnorm
+yn 42 min
+yn 42 min_subnorm
+yn -42 min
+yn -42 min_subnorm
diff --git a/sysdeps/ieee754/dbl-64/e_j1.c b/sysdeps/ieee754/dbl-64/e_j1.c
index bc7ca06..b7b8a9a 100644
--- a/sysdeps/ieee754/dbl-64/e_j1.c
+++ b/sysdeps/ieee754/dbl-64/e_j1.c
@@ -58,6 +58,7 @@ 
  *	   by method mentioned above.
  */
 
+#include <errno.h>
 #include <math.h>
 #include <math_private.h>
 
@@ -205,7 +206,10 @@  __ieee754_y1 (double x)
     }
   if (__glibc_unlikely (ix <= 0x3c900000))              /* x < 2**-54 */
     {
-      return (-tpi / x);
+      z = -tpi / x;
+      if (__isinf (z))
+	__set_errno (ERANGE);
+      return z;
     }
   z = x * x;
   u1 = U0[0] + z * U0[1]; z2 = z * z;
diff --git a/sysdeps/ieee754/flt-32/e_j1f.c b/sysdeps/ieee754/flt-32/e_j1f.c
index a180968..920e4b8 100644
--- a/sysdeps/ieee754/flt-32/e_j1f.c
+++ b/sysdeps/ieee754/flt-32/e_j1f.c
@@ -13,6 +13,7 @@ 
  * ====================================================
  */
 
+#include <errno.h>
 #include <math.h>
 #include <math_private.h>
 
@@ -135,7 +136,10 @@  __ieee754_y1f(float x)
 		return z;
 	}
 	if(__builtin_expect(ix<=0x33000000, 0)) {    /* x < 2**-25 */
-	    return(-tpi/x);
+	    z = -tpi / x;
+	    if (__isinff (z))
+		__set_errno (ERANGE);
+	    return z;
 	}
 	z = x*x;
 	u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4])));
diff --git a/sysdeps/ieee754/ldbl-128/e_j1l.c b/sysdeps/ieee754/ldbl-128/e_j1l.c
index 1264c95..f24dfa9 100644
--- a/sysdeps/ieee754/ldbl-128/e_j1l.c
+++ b/sysdeps/ieee754/ldbl-128/e_j1l.c
@@ -95,6 +95,7 @@ 
     License along with this library; if not, see
     <http://www.gnu.org/licenses/>.  */
 
+#include <errno.h>
 #include <math.h>
 #include <math_private.h>
 #include <float.h>
@@ -852,7 +853,12 @@  __ieee754_y1l (long double x)
     }
   xx = fabsl (x);
   if (xx <= 0x1p-114)
-    return -TWOOPI / x;
+    {
+      z = -TWOOPI / x;
+      if (__isinfl (z))
+	__set_errno (ERANGE);
+      return z;
+    }
   if (xx <= 2.0L)
     {
       /* 0 <= x <= 2 */
diff --git a/sysdeps/ieee754/ldbl-96/e_j1l.c b/sysdeps/ieee754/ldbl-96/e_j1l.c
index 5c0a2e1..88fcf13 100644
--- a/sysdeps/ieee754/ldbl-96/e_j1l.c
+++ b/sysdeps/ieee754/ldbl-96/e_j1l.c
@@ -71,6 +71,7 @@ 
  *	   by method mentioned above.
  */
 
+#include <errno.h>
 #include <math.h>
 #include <math_private.h>
 
@@ -234,7 +235,10 @@  __ieee754_y1l (long double x)
     }
   if (__glibc_unlikely (ix <= 0x3fbe))
     {				/* x < 2**-65 */
-      return (-tpi / x);
+      z = -tpi / x;
+      if (__isinfl (z))
+	__set_errno (ERANGE);
+      return z;
     }
   z = x * x;
  u = U0[0] + z * (U0[1] + z * (U0[2] + z * (U0[3] + z * (U0[4] + z * U0[5]))));