From patchwork Mon Jun 29 16:53:04 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Myers X-Patchwork-Id: 489354 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id AE098140783 for ; Tue, 30 Jun 2015 02:53:20 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=sourceware.org header.i=@sourceware.org header.b=wOGz5lqy; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:subject:message-id:mime-version :content-type; q=dns; s=default; b=CK9TnrOZ+h2Dnl/L/x+zHJzyGzURL Pkf2fZ4Msy8l/0cwbZ0kIii9NSO3zdNLLx7u1FoGDJHXeBKB8VBtf3zk4jkdzXHv svwES4rZqyjGw0h49Ua98ziyoE6lb1FFqp4JfP6TjLcfuLXbim9mJCRrtgQ6Wg+w 46j7M5N+nMW6B0= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:subject:message-id:mime-version :content-type; s=default; bh=D4kSaxcHNJJ1hLiSIIgmpDljEzA=; b=wOG z5lqyvOb967T6W+nJ9sroRZHwjMojhGxGNwLRwvSmuGvZqHASKPHm3rsyiIxPPxa QYbFKMu2z77Ivt5zSyp8Tm/s0f1+dZmEhZeMAFllKQxlFRAIFM0xVZ7nGr9LZT0J u1xtEAIIwx3MejMimyVwacceAzyKetfqvaddEuqw= Received: (qmail 126893 invoked by alias); 29 Jun 2015 16:53:14 -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 126880 invoked by uid 89); 29 Jun 2015 16:53:12 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: relay1.mentorg.com Date: Mon, 29 Jun 2015 16:53:04 +0000 From: Joseph Myers To: Subject: Fix j1, jn missing underflows (bug 16559) [committed] Message-ID: User-Agent: Alpine 2.10 (DEB 1266 2009-07-14) MIME-Version: 1.0 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. Committed. (auto-libm-test-out diffs omitted below.) 2015-06-29 Joseph Myers [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. diff --git a/math/auto-libm-test-in b/math/auto-libm-test-in index 75cf545..34b02c9 100644 --- a/math/auto-libm-test-in +++ b/math/auto-libm-test-in @@ -1812,6 +1812,11 @@ j1 0x1.ff00000000002p+840 j1 0x1p1023 j1 0x1p16382 j1 0x1p16383 +# Bug 18611: errno setting may be missing. +j1 min missing-errno +j1 -min missing-errno +j1 min_subnorm missing-errno +j1 -min_subnorm missing-errno # jn (0, x) == j0 (x). jn 0 -1.0 @@ -1836,6 +1841,11 @@ jn 1 1.5 jn 1 2.0 jn 1 8.0 jn 1 10.0 +# Bug 18611: errno setting may be missing. +jn 1 min missing-errno +jn 1 -min missing-errno +jn 1 min_subnorm missing-errno +jn 1 -min_subnorm missing-errno jn 3 -1.0 jn 3 0.0 @@ -1867,6 +1877,12 @@ jn 2 0x1p127 jn 2 0x1p1023 jn 2 0x1p16383 +# Bug 18611: errno setting may be missing. +jn 10 min missing-errno +jn 10 -min missing-errno +jn 10 min_subnorm missing-errno +jn 10 -min_subnorm missing-errno + lgamma max lgamma 1 lgamma 3 diff --git a/sysdeps/ieee754/dbl-64/e_j1.c b/sysdeps/ieee754/dbl-64/e_j1.c index 653f33a..26ffdfe 100644 --- a/sysdeps/ieee754/dbl-64/e_j1.c +++ b/sysdeps/ieee754/dbl-64/e_j1.c @@ -59,6 +59,7 @@ */ #include +#include #include #include @@ -124,8 +125,16 @@ __ieee754_j1 (double x) } if (__glibc_unlikely (ix < 0x3e400000)) /* |x|<2**-27 */ { - if (huge + x > one) - return 0.5 * x; /* inexact if x!=0 necessary */ + if (huge + x > one) /* inexact if x!=0 necessary */ + { + double ret = 0.5 * x; + if (fabs (ret) < DBL_MIN) + { + double force_underflow = ret * ret; + math_force_eval (force_underflow); + } + return ret; + } } z = x * x; r1 = z * R[0]; z2 = z * z; diff --git a/sysdeps/ieee754/dbl-64/e_jn.c b/sysdeps/ieee754/dbl-64/e_jn.c index b0ddd5e..ccef2dc 100644 --- a/sysdeps/ieee754/dbl-64/e_jn.c +++ b/sysdeps/ieee754/dbl-64/e_jn.c @@ -246,6 +246,11 @@ __ieee754_jn (int n, double x) } if (ret == 0) ret = __copysign (DBL_MIN, ret) * DBL_MIN; + else if (fabs (ret) < DBL_MIN) + { + double force_underflow = ret * ret; + math_force_eval (force_underflow); + } return ret; } strong_alias (__ieee754_jn, __jn_finite) diff --git a/sysdeps/ieee754/flt-32/e_j1f.c b/sysdeps/ieee754/flt-32/e_j1f.c index 7ffb57e..63de21f 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 ec5a81b..44a3761 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) diff --git a/sysdeps/ieee754/ldbl-128/e_jnl.c b/sysdeps/ieee754/ldbl-128/e_jnl.c index 14d65ff..a419994 100644 --- a/sysdeps/ieee754/ldbl-128/e_jnl.c +++ b/sysdeps/ieee754/ldbl-128/e_jnl.c @@ -297,6 +297,11 @@ __ieee754_jnl (int n, long double x) } if (ret == 0) ret = __copysignl (LDBL_MIN, ret) * LDBL_MIN; + else if (fabsl (ret) < LDBL_MIN) + { + long double force_underflow = ret * ret; + math_force_eval (force_underflow); + } return ret; } strong_alias (__ieee754_jnl, __jnl_finite) diff --git a/sysdeps/ieee754/ldbl-128ibm/e_jnl.c b/sysdeps/ieee754/ldbl-128ibm/e_jnl.c index 5d0a2b5..7594196 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_jnl.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_jnl.c @@ -297,6 +297,11 @@ __ieee754_jnl (int n, long double x) } if (ret == 0) ret = __copysignl (LDBL_MIN, ret) * LDBL_MIN; + else if (fabsl (ret) < LDBL_MIN) + { + long double force_underflow = ret * ret; + math_force_eval (force_underflow); + } return ret; } strong_alias (__ieee754_jnl, __jnl_finite) diff --git a/sysdeps/ieee754/ldbl-96/e_j1l.c b/sysdeps/ieee754/ldbl-96/e_j1l.c index 1bd5499..46e28df 100644 --- a/sysdeps/ieee754/ldbl-96/e_j1l.c +++ b/sysdeps/ieee754/ldbl-96/e_j1l.c @@ -72,6 +72,7 @@ */ #include +#include #include #include @@ -150,8 +151,16 @@ __ieee754_j1l (long double x) } if (__glibc_unlikely (ix < 0x3fde)) /* |x| < 2^-33 */ { - if (huge + x > one) - return 0.5 * x; /* inexact if x!=0 necessary */ + if (huge + x > one) /* inexact if x!=0 necessary */ + { + long double ret = 0.5 * x; + if (fabsl (ret) < LDBL_MIN) + { + long double force_underflow = ret * ret; + math_force_eval (force_underflow); + } + return ret; + } } z = x * x; r = z * (R[0] + z * (R[1]+ z * (R[2] + z * (R[3] + z * R[4])))); diff --git a/sysdeps/ieee754/ldbl-96/e_jnl.c b/sysdeps/ieee754/ldbl-96/e_jnl.c index 49c9c42..2f3a452 100644 --- a/sysdeps/ieee754/ldbl-96/e_jnl.c +++ b/sysdeps/ieee754/ldbl-96/e_jnl.c @@ -290,6 +290,11 @@ __ieee754_jnl (int n, long double x) } if (ret == 0) ret = __copysignl (LDBL_MIN, ret) * LDBL_MIN; + else if (fabsl (ret) < LDBL_MIN) + { + long double force_underflow = ret * ret; + math_force_eval (force_underflow); + } return ret; } strong_alias (__ieee754_jnl, __jnl_finite)