Set errno in expm1{,f} / log1p{,f}

Message ID 5D2498C8.3070605@riscy-ip.com
State New
Headers show
Series
  • Set errno in expm1{,f} / log1p{,f}
Related show

Commit Message

Joern Wolfgang Rennecke July 9, 2019, 1:38 p.m.
I find that the gcc test gcc.dg/torture/pr68264.c fails because expm1 / 
log1p fail to set errno.
Fixed with the attached patch.
OK to commit?
2019-07-09  Joern Rennecke  <joern.rennecke@riscy-ip.com>

	* libm/common/s_expm1.c ("math_config.h"): Include.
	(expm1): Use __math_oflow to set errno.
	* libm/common/s_log1p.c ("math_config.h"): Include.
	(log1p): Use __math_divzero and __math_invalid to set errno.
	* libm/common/sf_expm1.c ("math_config.h"): Include.
	(expm1f): Use __math_oflow to set errno.
	* libm/common/sf_log1p.c ("math_config.h"): Include.
	(log1pf): Use __math_divzero and __math_invalid to set errno.

Comments

Craig Howland via newlib July 9, 2019, 4:06 p.m. | #1
On 7/9/19 9:38 AM, Joern Wolfgang Rennecke wrote:
> I find that the gcc test gcc.dg/torture/pr68264.c fails because expm1 / log1p 

> fail to set errno.

> Fixed with the attached patch.

> OK to commit?

It is interesting to note that the Linux log1p man page says "These functions do 
not set errno."  This is in conflict with the C standard and POSIX which call 
for the normal errno behavior for it. Perhaps this explains why errno was not 
being set.

(Changes look good to me, but I don't have authority to approve committal.)

Craig
Jeff Johnston July 9, 2019, 5:09 p.m. | #2
Patch applied.

-- Jeff J.

On Tue, Jul 9, 2019 at 12:06 PM Craig Howland via newlib <
newlib@sourceware.org> wrote:

> On 7/9/19 9:38 AM, Joern Wolfgang Rennecke wrote:

> > I find that the gcc test gcc.dg/torture/pr68264.c fails because expm1 /

> log1p

> > fail to set errno.

> > Fixed with the attached patch.

> > OK to commit?

> It is interesting to note that the Linux log1p man page says "These

> functions do

> not set errno."  This is in conflict with the C standard and POSIX which

> call

> for the normal errno behavior for it. Perhaps this explains why errno was

> not

> being set.

>

> (Changes look good to me, but I don't have authority to approve committal.)

>

> Craig

>

>

>

>

>

Patch

Index: libm/common/s_expm1.c
===================================================================
--- libm/common/s_expm1.c	(revision 5756)
+++ libm/common/s_expm1.c	(working copy)
@@ -142,6 +142,7 @@  PORTABILITY
  */
 
 #include "fdlibm.h"
+#include "math_config.h"
 
 #ifndef _DOUBLE_IS_32BITS
 
@@ -190,7 +191,7 @@  Q5  =  -2.01099218183624371326e-07; /* B
 		         return x+x; 	 /* NaN */
 		    else return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */
 	        }
-	        if(x > o_threshold) return huge*huge; /* overflow */
+	        if(x > o_threshold) return __math_oflow (0); /* overflow */
 	    }
 	    if(xsb!=0) { /* x < -56*ln2, return -1.0 with inexact */
 		if(x+tiny<0.0)		/* raise inexact */
Index: libm/common/s_log1p.c
===================================================================
--- libm/common/s_log1p.c	(revision 5756)
+++ libm/common/s_log1p.c	(working copy)
@@ -113,6 +113,7 @@  Interface Definition (Issue 2).
  */
 
 #include "fdlibm.h"
+#include "math_config.h"
 
 #ifndef _DOUBLE_IS_32BITS
 
@@ -154,8 +155,10 @@  static double zero = 0.0;
 	k = 1;
 	if (hx < 0x3FDA827A) {			/* x < 0.41422  */
 	    if(ax>=0x3ff00000) {		/* x <= -1.0 */
-		if(x==-1.0) return -two54/zero; /* log1p(-1)=+inf */
-		else return (x-x)/(x-x);	/* log1p(x<-1)=NaN */
+		if(x==-1.0)
+		    return __math_divzero (1);	/* log1p(-1)=-inf */
+		else
+		    return __math_invalid (x);	/* log1p(x<-1)=NaN */
 	    }
 	    if(ax<0x3e200000) {			/* |x| < 2**-29 */
 		if(two54+x>zero			/* raise inexact */
Index: libm/common/sf_expm1.c
===================================================================
--- libm/common/sf_expm1.c	(revision 5756)
+++ libm/common/sf_expm1.c	(working copy)
@@ -14,6 +14,7 @@ 
  */
 
 #include "fdlibm.h"
+#include "math_config.h"
 
 #ifdef __v810__
 #define const
@@ -60,7 +61,7 @@  Q5  =  -2.0109921195e-07; /* 0xb457edbb
 	    if(FLT_UWORD_IS_INFINITE(hx))
 		return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */
 	    if(xsb == 0 && hx > FLT_UWORD_LOG_MAX) /* if x>=o_threshold */
-		return huge*huge; /* overflow */
+		return __math_oflowf (0); /* overflow */
 	    if(xsb!=0) { /* x < -27*ln2, return -1.0 with inexact */
 		if(x+tiny<(float)0.0)	/* raise inexact */
 		return tiny-one;	/* return -1 */
Index: libm/common/sf_log1p.c
===================================================================
--- libm/common/sf_log1p.c	(revision 5756)
+++ libm/common/sf_log1p.c	(working copy)
@@ -14,6 +14,7 @@ 
  */
 
 #include "fdlibm.h"
+#include "math_config.h"
 
 #ifdef __STDC__
 static const float
@@ -54,8 +55,10 @@  static float zero = 0.0;
 	if (!FLT_UWORD_IS_FINITE(hx)) return x+x;
 	if (hx < 0x3ed413d7) {			/* x < 0.41422  */
 	    if(ax>=0x3f800000) {		/* x <= -1.0 */
-		if(x==(float)-1.0) return -two25/zero; /* log1p(-1)=+inf */
-		else return (x-x)/(x-x);	/* log1p(x<-1)=NaN */
+		if(x==(float)-1.0)
+		    return __math_divzero (1); /* log1p(-1)=-inf */
+		else
+		    return __math_invalid (x);	/* log1p(x<-1)=NaN */
 	    }
 	    if(ax<0x31000000) {			/* |x| < 2**-29 */
 		if(two25+x>zero			/* raise inexact */