From patchwork Wed Jun 13 22:01:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tulio Magno Quites Machado Filho X-Patchwork-Id: 27823 X-Patchwork-Delegate: joseph@codesourcery.com Received: (qmail 79262 invoked by alias); 13 Jun 2018 22:01:50 -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 79242 invoked by uid 89); 13 Jun 2018 22:01:49 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=zhi X-HELO: mx0a-001b2d01.pphosted.com From: Tulio Magno Quites Machado Filho To: libc-alpha@sourceware.org Subject: [PATCH] Fix ldbl-128ibm fma (Inf, Inf, finite) (bug 23272) Date: Wed, 13 Jun 2018 19:01:36 -0300 X-TM-AS-GCONF: 00 x-cbid: 18061322-0036-0000-0000-000009FCCAD2 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00009185; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000265; SDB=6.01046542; UDB=6.00535991; IPR=6.00825517; MB=3.00021631; MTD=3.00000008; XFM=3.00000015; UTC=2018-06-13 22:01:45 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18061322-0037-0000-0000-000047BAB018 Message-Id: <20180613220136.11438-1-tuliom@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-06-13_09:, , signatures=0 This solution is mainly based on Joseph's fix at commit ca121b117f2c9c97a4c121334481a96c94fef3a0. It has extra differences because: - part of the non-finite arguments were already being treated; - when x and y are +-Inf and z if finite, an overflow can be generated. Tested on powerpc[|64|64le]. 2018-06-13 Tulio Magno Quites Machado Filho [BZ 23272] * sysdeps/ieee754/ldbl-128ibm/s_fmal.c (__fmal): Handle all cases of non-finite arguments. Signed-off-by: Tulio Magno Quites Machado Filho --- sysdeps/ieee754/ldbl-128ibm/s_fmal.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/sysdeps/ieee754/ldbl-128ibm/s_fmal.c b/sysdeps/ieee754/ldbl-128ibm/s_fmal.c index e72a3e4d59..afba1ca727 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_fmal.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_fmal.c @@ -127,37 +127,30 @@ long double __fmal (long double x, long double y, long double z) { double xhi, xlo, yhi, ylo, zhi, zlo; - int64_t hx, hy, hz; - int xexp, yexp, zexp; double scale_val; int scale_exp; ldbl_unpack (x, &xhi, &xlo); - EXTRACT_WORDS64 (hx, xhi); - xexp = (hx & 0x7ff0000000000000LL) >> 52; ldbl_unpack (y, &yhi, &ylo); - EXTRACT_WORDS64 (hy, yhi); - yexp = (hy & 0x7ff0000000000000LL) >> 52; ldbl_unpack (z, &zhi, &zlo); - EXTRACT_WORDS64 (hz, zhi); - zexp = (hz & 0x7ff0000000000000LL) >> 52; - /* If z is Inf or NaN, but x and y are finite, avoid any exceptions - from computing x * y. */ - if (zexp == 0x7ff && xexp != 0x7ff && yexp != 0x7ff) + if (__glibc_unlikely (!isfinite (x) || !isfinite (y) || x == 0 || y == 0)) + if (!isfinite (x) && !isfinite (y) && isfinite(z)) + /* Compute the result as x * y to avoid an overflow. */ + return x * y; + else + /* If x or y is Inf, NaN or zero compute as x * y + z. */ + return (x * y) + z; + else if (__glibc_unlikely (!isfinite (z))) + /* If z is Inf, but x and y are finite, the result should be z + rather than NaN. */ return (z + x) + y; - /* If z is zero and x are y are nonzero, compute the result as x * y + /* If z is zero and x and y are nonzero, compute the result as x * y to avoid the wrong sign of a zero result if x * y underflows to 0. */ - if (z == 0 && x != 0 && y != 0) + if (z == 0) return x * y; - /* If x or y or z is Inf/NaN, or if x * y is zero, compute as x * y - + z. */ - if (xexp == 0x7ff || yexp == 0x7ff || zexp == 0x7ff - || x == 0 || y == 0) - return (x * y) + z; - { SET_RESTORE_ROUND (FE_TONEAREST);