aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/ieee754
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2015-09-18 20:00:48 +0000
committerJoseph Myers <joseph@codesourcery.com>2015-09-18 20:00:48 +0000
commitc8235dda728c4452f57c4c0d1bccc4e9a67da80c (patch)
treeae521c94b4648e089ee442cf8991963e7ffd97fe /sysdeps/ieee754
parentfe8c2b33aed067282ecac0cc3fdff1feef88548b (diff)
downloadglibc-c8235dda728c4452f57c4c0d1bccc4e9a67da80c.zip
glibc-c8235dda728c4452f57c4c0d1bccc4e9a67da80c.tar.gz
glibc-c8235dda728c4452f57c4c0d1bccc4e9a67da80c.tar.bz2
Avoid excess range overflowing results from cosh, sinh, lgamma (bug 18980).
Various i386 libm functions return values with excess range and precision; Wilco Dijkstra's patches to make isfinite etc. expand inline cause this pre-existing issue to result in test failures (when e.g. a result that overflows float but not long double gets counted as overflowing for some purposes but not others). This patch addresses those cases arising from functions defined in C, adding a math_narrow_eval macro that forces values to memory to eliminate excess precision if FLT_EVAL_METHOD indicates this is needed, and is a no-op otherwise. I'll convert existing uses of volatile and asm for this purpose to use the new macro later, once i386 has clean test results again (which requires fixes for .S files as well). Tested for x86_64 and x86. Committed. [BZ #18980] * sysdeps/generic/math_private.h: Include <float.h>. (math_narrow_eval): New macro. [FLT_EVAL_METHOD != 0] (excess_precision): Likewise. * sysdeps/ieee754/dbl-64/e_cosh.c (__ieee754_cosh): Use math_narrow_eval on overflowing return value. * sysdeps/ieee754/dbl-64/e_lgamma_r.c (__ieee754_lgamma_r): Likewise. * sysdeps/ieee754/dbl-64/e_sinh.c (__ieee754_sinh): Likewise. * sysdeps/ieee754/flt-32/e_coshf.c (__ieee754_coshf): Likewise. * sysdeps/ieee754/flt-32/e_lgammaf_r.c (__ieee754_lgammaf_r): Likewise. * sysdeps/ieee754/flt-32/e_sinhf.c (__ieee754_sinhf): Likewise.
Diffstat (limited to 'sysdeps/ieee754')
-rw-r--r--sysdeps/ieee754/dbl-64/e_cosh.c2
-rw-r--r--sysdeps/ieee754/dbl-64/e_lgamma_r.c2
-rw-r--r--sysdeps/ieee754/dbl-64/e_sinh.c2
-rw-r--r--sysdeps/ieee754/flt-32/e_coshf.c2
-rw-r--r--sysdeps/ieee754/flt-32/e_lgammaf_r.c2
-rw-r--r--sysdeps/ieee754/flt-32/e_sinhf.c2
6 files changed, 6 insertions, 6 deletions
diff --git a/sysdeps/ieee754/dbl-64/e_cosh.c b/sysdeps/ieee754/dbl-64/e_cosh.c
index af3910d..52a5d50 100644
--- a/sysdeps/ieee754/dbl-64/e_cosh.c
+++ b/sysdeps/ieee754/dbl-64/e_cosh.c
@@ -83,6 +83,6 @@ __ieee754_cosh (double x)
return x * x;
/* |x| > overflowthresold, cosh(x) overflow */
- return huge * huge;
+ return math_narrow_eval (huge * huge);
}
strong_alias (__ieee754_cosh, __cosh_finite)
diff --git a/sysdeps/ieee754/dbl-64/e_lgamma_r.c b/sysdeps/ieee754/dbl-64/e_lgamma_r.c
index ea8a9b4..da158cb 100644
--- a/sysdeps/ieee754/dbl-64/e_lgamma_r.c
+++ b/sysdeps/ieee754/dbl-64/e_lgamma_r.c
@@ -296,7 +296,7 @@ __ieee754_lgamma_r(double x, int *signgamp)
r = (x-half)*(t-one)+w;
} else
/* 2**58 <= x <= inf */
- r = x*(__ieee754_log(x)-one);
+ r = math_narrow_eval (x*(__ieee754_log(x)-one));
/* NADJ is set for negative arguments but not otherwise,
resulting in warnings that it may be used uninitialized
although in the cases where it is used it has always been
diff --git a/sysdeps/ieee754/dbl-64/e_sinh.c b/sysdeps/ieee754/dbl-64/e_sinh.c
index c99d283..291bfad 100644
--- a/sysdeps/ieee754/dbl-64/e_sinh.c
+++ b/sysdeps/ieee754/dbl-64/e_sinh.c
@@ -89,6 +89,6 @@ __ieee754_sinh (double x)
}
/* |x| > overflowthresold, sinh(x) overflow */
- return x * shuge;
+ return math_narrow_eval (x * shuge);
}
strong_alias (__ieee754_sinh, __sinh_finite)
diff --git a/sysdeps/ieee754/flt-32/e_coshf.c b/sysdeps/ieee754/flt-32/e_coshf.c
index dedda47..7b22375 100644
--- a/sysdeps/ieee754/flt-32/e_coshf.c
+++ b/sysdeps/ieee754/flt-32/e_coshf.c
@@ -58,6 +58,6 @@ __ieee754_coshf (float x)
if(ix>=0x7f800000) return x*x;
/* |x| > overflowthresold, cosh(x) overflow */
- return huge*huge;
+ return math_narrow_eval (huge*huge);
}
strong_alias (__ieee754_coshf, __coshf_finite)
diff --git a/sysdeps/ieee754/flt-32/e_lgammaf_r.c b/sysdeps/ieee754/flt-32/e_lgammaf_r.c
index 424c4e7..45a62c0 100644
--- a/sysdeps/ieee754/flt-32/e_lgammaf_r.c
+++ b/sysdeps/ieee754/flt-32/e_lgammaf_r.c
@@ -232,7 +232,7 @@ __ieee754_lgammaf_r(float x, int *signgamp)
r = (x-half)*(t-one)+w;
} else
/* 2**26 <= x <= inf */
- r = x*(__ieee754_logf(x)-one);
+ r = math_narrow_eval (x*(__ieee754_logf(x)-one));
/* NADJ is set for negative arguments but not otherwise,
resulting in warnings that it may be used uninitialized
although in the cases where it is used it has always been
diff --git a/sysdeps/ieee754/flt-32/e_sinhf.c b/sysdeps/ieee754/flt-32/e_sinhf.c
index 17c2219..a24fa0c 100644
--- a/sysdeps/ieee754/flt-32/e_sinhf.c
+++ b/sysdeps/ieee754/flt-32/e_sinhf.c
@@ -59,6 +59,6 @@ __ieee754_sinhf(float x)
}
/* |x| > overflowthresold, sinh(x) overflow */
- return x*shuge;
+ return math_narrow_eval (x*shuge);
}
strong_alias (__ieee754_sinhf, __sinhf_finite)