public inbox for newlib-cvs@sourceware.org
help / color / mirror / Atom feed
From: Corinna Vinschen <corinna@sourceware.org>
To: newlib-cvs@sourceware.org
Subject: [newlib-cygwin] Fix powf overflow handling in non-nearest rounding mode
Date: Tue, 11 Dec 2018 11:55:00 -0000	[thread overview]
Message-ID: <20181211115551.95415.qmail@sourceware.org> (raw)

https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=df6915f029ac9acd2b479ea898388cbd7dda4974

commit df6915f029ac9acd2b479ea898388cbd7dda4974
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
Date:   Mon Dec 10 14:40:01 2018 +0000

    Fix powf overflow handling in non-nearest rounding mode
    
    The threshold value at which powf overflows depends on the rounding mode
    and the current check did not take this into account. So when the result
    was rounded away from zero it could become infinity without setting
    errno to ERANGE.
    
    Example: pow(0x1.7ac7cp+5, 23) is 0x1.fffffep+127 + 0.1633ulp
    
    If the result goes above 0x1.fffffep+127 + 0.5ulp then errno is set,
    which is fine in nearest rounding mode, but
    
      powf(0x1.7ac7cp+5, 23) is inf in upward rounding mode
      powf(-0x1.7ac7cp+5, 23) is -inf in downward rounding mode
    
    and the previous implementation did not set errno in these cases.
    
    The fix tries to avoid affecting the common code path or calling a
    function that may introduce a stack frame, so float arithmetics is used
    to check the rounding mode and the threshold is selected accordingly.

Diff:
---
 newlib/libm/common/sf_pow.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/newlib/libm/common/sf_pow.c b/newlib/libm/common/sf_pow.c
index f7b22b6..2946c61 100644
--- a/newlib/libm/common/sf_pow.c
+++ b/newlib/libm/common/sf_pow.c
@@ -220,7 +220,17 @@ powf (float x, float y)
     {
       /* |y*log(x)| >= 126.  */
       if (ylogx > 0x1.fffffffd1d571p+6 * POWF_SCALE)
+	/* |x^y| > 0x1.ffffffp127.  */
 	return __math_oflowf (sign_bias);
+      if (WANT_ROUNDING && WANT_ERRNO
+	  && ylogx > 0x1.fffffffa3aae2p+6 * POWF_SCALE)
+	/* |x^y| > 0x1.fffffep127, check if we round away from 0.  */
+	if ((!sign_bias
+	     && eval_as_float (1.0f + opt_barrier_float (0x1p-25f)) != 1.0f)
+	    || (sign_bias
+		&& eval_as_float (-1.0f - opt_barrier_float (0x1p-25f))
+		     != -1.0f))
+	  return __math_oflowf (sign_bias);
       if (ylogx <= -150.0 * POWF_SCALE)
 	return __math_uflowf (sign_bias);
 #if WANT_ERRNO_UFLOW


                 reply	other threads:[~2018-12-11 11:55 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181211115551.95415.qmail@sourceware.org \
    --to=corinna@sourceware.org \
    --cc=newlib-cvs@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).