public inbox for newlib@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Don't call double rint from float powf.
@ 2017-12-12  0:14 Jim Wilson
  2017-12-12  3:45 ` Craig Howland
  2017-12-12 19:39 ` [PATCH v2] " Jim Wilson
  0 siblings, 2 replies; 8+ messages in thread
From: Jim Wilson @ 2017-12-12  0:14 UTC (permalink / raw)
  To: newlib; +Cc: Jim Wilson

This is the first patch of two to fix problems with the powf code.  I haven't
written the other patch yet.

For targets that have only single float support, such as RISC-V rv32imafc, a
program using powf ends up pulling in soft-float adddf3 and subdf3 routines.
These come from the double rint call, which should be float rintf instead.
This makes a significant difference in the size of the resulting program.

I tested this with a simple testcase, with an rint function that calls abort
to verify that I'm testing the right code path.  Compiling with
"gcc -fno-builtin" I get for the patched and unpatched newlib

gamma02:2195$ ls -lt a.out*
-rwxrwxr-x 1 jimw jimw 47012 Dec 11 15:01 a.out
-rwxrwxr-x 1 jimw jimw 75680 Dec 11 14:46 a.out.unpatched
gamma02:2196$ 

So the result with the patch is about 60% of the size without the patch.  The
test program gives the correct result with the patch.  I also ran the newlib
make check, which passed with no regression, but I see it doesn't do much
useful.

	newlib/
	* libm/math/wf_pow.c (powf): Call rintf instead of rint.
---
 newlib/libm/math/wf_pow.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/newlib/libm/math/wf_pow.c b/newlib/libm/math/wf_pow.c
index be453558b..4ca0dc79d 100644
--- a/newlib/libm/math/wf_pow.c
+++ b/newlib/libm/math/wf_pow.c
@@ -127,11 +127,11 @@
 		    if (_LIB_VERSION == _SVID_) {
 		       exc.retval = HUGE;
 		       y *= 0.5;
-		       if(x<0.0&&rint(y)!=y) exc.retval = -HUGE;
+		       if(x<0.0&&rintf(y)!=y) exc.retval = -HUGE;
 		    } else {
 		       exc.retval = HUGE_VAL;
                        y *= 0.5;
-		       if(x<0.0&&rint(y)!=y) exc.retval = -HUGE_VAL;
+		       if(x<0.0&&rintf(y)!=y) exc.retval = -HUGE_VAL;
 		    }
 		    if (_LIB_VERSION == _POSIX_)
 		        errno = ERANGE;
-- 
2.14.1

Testcase:

#include <stdlib.h>
#include <math.h>

int
main (void)
{
  float f = powf (-2.0, -2.0);
  if (f != 0.25)
    abort ();

  float g = powf (-2.0, -3.0);
  if (g != -0.125)
    abort ();

  float a = powf (-2.0, 129);
  if (a != -__builtin_inff ())
    abort ();

  float b = powf (-2.0, 130);
  if (b != __builtin_inff ())
    abort ();

  return 0;
}

double
rint (double x)
{
  abort ();
}

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2017-12-13 10:07 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-12  0:14 [PATCH] Don't call double rint from float powf Jim Wilson
2017-12-12  3:45 ` Craig Howland
2017-12-12 12:49   ` Corinna Vinschen
2017-12-12 18:14     ` Jim Wilson
2017-12-12 18:05   ` Jim Wilson
2017-12-12 19:00     ` Craig Howland
2017-12-12 19:39 ` [PATCH v2] " Jim Wilson
2017-12-13 10:35   ` 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).