public inbox for newlib-cvs@sourceware.org
help / color / mirror / Atom feed
* [newlib-cygwin] Fix powf overflow handling in non-nearest rounding mode
@ 2018-12-11 11:55 Corinna Vinschen
  0 siblings, 0 replies; only message in thread
From: Corinna Vinschen @ 2018-12-11 11:55 UTC (permalink / raw)
  To: newlib-cvs

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


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2018-12-11 11:55 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-11 11:55 [newlib-cygwin] Fix powf overflow handling in non-nearest rounding mode Corinna Vinschen

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).