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;