From patchwork Fri Jun 20 23:17:25 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Myers X-Patchwork-Id: 1630 Received: (qmail 11341 invoked by alias); 20 Jun 2014 23:17:34 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 11326 invoked by uid 89); 20 Jun 2014 23:17:33 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL, BAYES_00 autolearn=ham version=3.3.2 X-HELO: relay1.mentorg.com Date: Fri, 20 Jun 2014 23:17:25 +0000 From: "Joseph S. Myers" To: Subject: Fix exp10 spurious underflows (bug 16560) Message-ID: MIME-Version: 1.0 This patch fixes spurious underflows from exp10 for arguments near 0 (part of bug 16560; that bug also includes spurious underflows from exp2, which are not fixed by this patch). The problem is underflows in the internal computation converting the exp10 argument to arguments for exp (with extra precision), and the fix is simply to return 1 early for arguments near enough to 0 (just as arguments with large enough magnitude have their own overflow / underflow logic at the start of the function). Tested x86_64 and x86 and ulps updated accordingly; also tested for powerpc32 and mips64 to validate the ldbl-128ibm and ldbl-128 changes. (auto-libm-test-out diffs omitted below.) 2014-06-20 Joseph Myers [BZ #16560] * sysdeps/ieee754/dbl-64/e_exp10.c (__ieee754_exp10): Return 1 for arguments close to 0. * sysdeps/ieee754/ldbl-128/e_exp10l.c (__ieee754_exp10l): Likewise. * sysdeps/ieee754/ldbl-128ibm/e_exp10l.c (__ieee754_exp10l): Likewise. * math/auto-libm-test-in: Add more tests of exp10. * math/auto-libm-test-out: Regenerated. * sysdeps/x86_64/fpu/libm-test-ulps: Update. diff --git a/math/auto-libm-test-in b/math/auto-libm-test-in index 6edad5a..06b3f4b 100644 --- a/math/auto-libm-test-in +++ b/math/auto-libm-test-in @@ -889,6 +889,24 @@ exp10 -max exp10 0.75 # GCC bug 59666: results on directed rounding may be incorrect. exp10 0x1.348e45573a1dd72cp+8 xfail-rounding:ldbl-128ibm +exp10 0x1p-10 +exp10 -0x1p-10 +exp10 0x1p-20 +exp10 -0x1p-20 +exp10 0x1p-30 +exp10 -0x1p-30 +exp10 0x1p-40 +exp10 -0x1p-40 +exp10 0x1p-50 +exp10 -0x1p-50 +exp10 0x1p-60 +exp10 -0x1p-60 +exp10 0x1p-100 +exp10 -0x1p-100 +exp10 min +exp10 -min +exp10 min_subnorm +exp10 -min_subnorm exp2 0 exp2 -0 diff --git a/sysdeps/ieee754/dbl-64/e_exp10.c b/sysdeps/ieee754/dbl-64/e_exp10.c index eac609b..59cb2ff 100644 --- a/sysdeps/ieee754/dbl-64/e_exp10.c +++ b/sysdeps/ieee754/dbl-64/e_exp10.c @@ -35,6 +35,8 @@ __ieee754_exp10 (double arg) return DBL_MIN * DBL_MIN; else if (arg > DBL_MAX_10_EXP + 1) return DBL_MAX * DBL_MAX; + else if (fabs (arg) < 0x1p-56) + return 1.0; GET_LOW_WORD (lx, arg); lx &= 0xf8000000; diff --git a/sysdeps/ieee754/ldbl-128/e_exp10l.c b/sysdeps/ieee754/ldbl-128/e_exp10l.c index 3c50963..da70995 100644 --- a/sysdeps/ieee754/ldbl-128/e_exp10l.c +++ b/sysdeps/ieee754/ldbl-128/e_exp10l.c @@ -35,6 +35,8 @@ __ieee754_exp10l (long double arg) return LDBL_MIN * LDBL_MIN; else if (arg > LDBL_MAX_10_EXP + 1) return LDBL_MAX * LDBL_MAX; + else if (fabsl (arg) < 0x1p-116L) + return 1.0L; u.value = arg; u.parts64.lsw &= 0xfe00000000000000LL; diff --git a/sysdeps/ieee754/ldbl-128ibm/e_exp10l.c b/sysdeps/ieee754/ldbl-128ibm/e_exp10l.c index 5c68eb5..a0e8a3e 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_exp10l.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_exp10l.c @@ -35,6 +35,8 @@ __ieee754_exp10l (long double arg) return LDBL_MIN * LDBL_MIN; else if (arg > LDBL_MAX_10_EXP + 1) return LDBL_MAX * LDBL_MAX; + else if (fabsl (arg) < 0x1p-109L) + return 1.0L; u.ld = arg; arg_high = u.d[0].d; diff --git a/sysdeps/x86_64/fpu/libm-test-ulps b/sysdeps/x86_64/fpu/libm-test-ulps index 92fef5a..3354294 100644 --- a/sysdeps/x86_64/fpu/libm-test-ulps +++ b/sysdeps/x86_64/fpu/libm-test-ulps @@ -1359,7 +1359,9 @@ ldouble: 1 Function: "exp10_downward": double: 1 +float: 1 idouble: 1 +ifloat: 1 ildouble: 2 ldouble: 2 @@ -1371,7 +1373,9 @@ ldouble: 1 Function: "exp10_towardzero": double: 1 +float: 1 idouble: 1 +ifloat: 1 ildouble: 1 ldouble: 1 @@ -1717,13 +1721,17 @@ ldouble: 1 Function: "pow10_downward": double: 1 +float: 1 idouble: 1 +ifloat: 1 ildouble: 2 ldouble: 2 Function: "pow10_towardzero": double: 1 +float: 1 idouble: 1 +ifloat: 1 ildouble: 1 ldouble: 1