This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Don't call double rint from float powf.


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 ();
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]