From patchwork Tue Jun 24 20:24:44 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Myers X-Patchwork-Id: 1703 Received: (qmail 30257 invoked by alias); 24 Jun 2014 20:24:53 -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 30247 invoked by uid 89); 24 Jun 2014 20:24:52 -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: Tue, 24 Jun 2014 20:24:44 +0000 From: "Joseph S. Myers" To: Subject: Fix ldbl-128 erfl spurious underflows (bug 16287) Message-ID: MIME-Version: 1.0 This patch fixes bug 16287, spurious underflows from ldbl-128 erfl arising from it calling erfcl for arguments with absolute value at least 1.0, although for large positive arguments erfcl correctly underflows but erfl shouldn't. The fix is simply to avoid calling erfcl, and just return 1, for arguments above a cut-off large enough that erfl correctly rounds to-nearest as 1 but not so large that erfcl underflows. Tested mips64. Also tested x86_64 and x86 to confirm the new tests (taken from the tests of erfc) don't cause any problems there; no ulps updates needed. (auto-libm-test-out diffs omitted below.) 2014-06-24 Joseph Myers [BZ #16287] * sysdeps/ieee754/ldbl-128/s_erfl.c (__erfl): Return 1 without calling __erfcl for arguments at least 16. * math/auto-libm-test-in: Add more tests of erf. * math/auto-libm-test-out: Regenerated. diff --git a/math/auto-libm-test-in b/math/auto-libm-test-in index 4eaa013..79d276c 100644 --- a/math/auto-libm-test-in +++ b/math/auto-libm-test-in @@ -803,6 +803,16 @@ erf 0x1.c5bf94p-127 erf 0x3.8b7fa8p-128 erf -0x3.8b7f12369ded8p-1024 erf 0x3.8b7f12369ded5518p-16384 +erf 26.0 +erf 28.0 +erf 100 +erf 106 +erf 106.5 +erf 106.625 +erf 107 +erf 108 +erf 1000 +erf max erfc 0.0 erfc -0 diff --git a/sysdeps/ieee754/ldbl-128/s_erfl.c b/sysdeps/ieee754/ldbl-128/s_erfl.c index 35ca8c1..f44d481 100644 --- a/sysdeps/ieee754/ldbl-128/s_erfl.c +++ b/sysdeps/ieee754/ldbl-128/s_erfl.c @@ -769,6 +769,8 @@ __erfl (long double x) if (ix >= 0x3fff0000) /* |x| >= 1.0 */ { + if (ix >= 0x40030000 && sign > 0) + return one; y = __erfcl (x); return (one - y); /* return (one - __erfcl (x)); */