Set errno for y1 overflow (bug 17050)
Commit Message
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
Ping. This patch
<https://sourceware.org/ml/libc-alpha/2014-06/msg00322.html> is pending
review.
Ping^2. This patch
<https://sourceware.org/ml/libc-alpha/2014-06/msg00322.html> is still
pending review.
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
@@ -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
@@ -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;
@@ -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])));
@@ -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 */
@@ -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]))));