From 63dbe5f32238858c7b953b867ed0588c7808dd4f Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Mon, 29 Jun 2015 16:52:16 +0000 Subject: Fix j1, jn missing underflows (bug 16559). Similar to various other bugs in this area, j1 and jn implementations can fail to raise the underflow exception when the internal computation is exact although the actual function is inexact. This patch forces the exception in a similar way to other such fixes. (The ldbl-128 / ldbl-128ibm j1l implementation is different and doesn't need a change for this until spurious underflows in it are fixed.) Tested for x86_64, x86, mips64 and powerpc. [BZ #16559] * sysdeps/ieee754/dbl-64/e_j1.c: Include . (__ieee754_j1): Force underflow exception for small results. * sysdeps/ieee754/dbl-64/e_jn.c (__ieee754_jn): Likewise. * sysdeps/ieee754/flt-32/e_j1f.c: Include . (__ieee754_j1f): Force underflow exception for small results. * sysdeps/ieee754/flt-32/e_jnf.c (__ieee754_jnf): Likewise. * sysdeps/ieee754/ldbl-128/e_jnl.c (__ieee754_jnl): Likewise. * sysdeps/ieee754/ldbl-128ibm/e_jnl.c (__ieee754_jnl): Likewise. * sysdeps/ieee754/ldbl-96/e_j1l.c: Include . (__ieee754_j1l): Force underflow exception for small results. * sysdeps/ieee754/ldbl-96/e_jnl.c (__ieee754_jnl): Likewise. * math/auto-libm-test-in: Add more tests of j1 and jn. * math/auto-libm-test-out: Regenerated. --- sysdeps/ieee754/flt-32/e_j1f.c | 10 +++++++++- sysdeps/ieee754/flt-32/e_jnf.c | 4 ++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'sysdeps/ieee754/flt-32') diff --git a/sysdeps/ieee754/flt-32/e_j1f.c b/sysdeps/ieee754/flt-32/e_j1f.c index 7ffb57e806..63de21f609 100644 --- a/sysdeps/ieee754/flt-32/e_j1f.c +++ b/sysdeps/ieee754/flt-32/e_j1f.c @@ -14,6 +14,7 @@ */ #include +#include #include #include @@ -69,7 +70,14 @@ __ieee754_j1f(float x) else return z; } if(__builtin_expect(ix<0x32000000, 0)) { /* |x|<2**-27 */ - if(huge+x>one) return (float)0.5*x;/* inexact if x!=0 necessary */ + if(huge+x>one) { /* inexact if x!=0 necessary */ + float ret = (float) 0.5 * x; + if (fabsf (ret) < FLT_MIN) { + float force_underflow = ret * ret; + math_force_eval (force_underflow); + } + return ret; + } } z = x*x; r = z*(r00+z*(r01+z*(r02+z*r03))); diff --git a/sysdeps/ieee754/flt-32/e_jnf.c b/sysdeps/ieee754/flt-32/e_jnf.c index ec5a81b653..44a3761adb 100644 --- a/sysdeps/ieee754/flt-32/e_jnf.c +++ b/sysdeps/ieee754/flt-32/e_jnf.c @@ -170,6 +170,10 @@ __ieee754_jnf(int n, float x) } if (ret == 0) ret = __copysignf (FLT_MIN, ret) * FLT_MIN; + else if (fabsf (ret) < FLT_MIN) { + float force_underflow = ret * ret; + math_force_eval (force_underflow); + } return ret; } strong_alias (__ieee754_jnf, __jnf_finite) -- cgit 1.4.1