[PATCH] Don't do double divide in powf.

Jim Wilson jimw@sifive.com
Tue Dec 12 10:51:00 GMT 2017


Similar to the previous powf patch, we have a double 0.0/0.0 divide being
used to generate a NaN, which on a single float only target pulls in divdf3.
wf_log.c calls nan instead.  I fixed powf to do the same.

With this patch, and a small testcase, I see

gamma02:2368$ ls -lt a.out*
-rwxrwxr-x 1 jimw jimw 32912 Dec 11 19:35 a.out
-rwxrwxr-x 1 jimw jimw 46992 Dec 11 18:54 a.out.unpatched
gamma02:2369$ 

So the patched code is about 70% of the size of the unpatched code.

This was tested with the testcase included below, and a newlib make check.

Jim

	newlib/
	* libm/math/wf_pow.c (powf): Call nan instead of double 0.0/0.0.
---
 newlib/libm/math/wf_pow.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/newlib/libm/math/wf_pow.c b/newlib/libm/math/wf_pow.c
index be453558b..1e0447173 100644
--- a/newlib/libm/math/wf_pow.c
+++ b/newlib/libm/math/wf_pow.c
@@ -108,7 +108,7 @@
 		    if (_LIB_VERSION == _SVID_) 
 		        exc.retval = 0.0;
 		    else 
-		        exc.retval = 0.0/0.0;	/* X/Open allow NaN */
+		        exc.retval = nan("");	/* X/Open allow NaN */
 		    if (_LIB_VERSION == _POSIX_) 
 		        errno = EDOM;
 		    else if (!matherr(&exc)) {
-- 
2.14.1

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

int
main (void)
{
  union { float f; int i; } u, v;
  v.f = __builtin_nan ("");

  float f = powf (-2.0, -2.2);
  u.f = f;
  if (u.i != v.i)
    abort ();

  float g = powf (-2.0, 3.3);
  u.f = g;
  if (u.i != v.i)
    abort ();

  return 0;
}



More information about the Newlib mailing list