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]

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


On 12/11/2017 07:08 PM, Jim Wilson wrote:
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;
To be most rigorous, "0.0" on the same lines as the rintf() should be "0.0F" (as otherwise the comparison strictly should be done in double).  (Not addressing the exact change you are making, but is the same class of fix and are on the same line of source code.)


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