about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--sysdeps/ieee754/dbl-64/e_pow.c10
-rw-r--r--sysdeps/ieee754/flt-32/e_powf.c4
-rw-r--r--sysdeps/ieee754/ldbl-128/e_powl.c5
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/e_powl.c4
5 files changed, 21 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 42a432d6e1..2da454aeb4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2016-12-02  Joseph Myers  <joseph@codesourcery.com>
 
+	[BZ #20916]
+	* sysdeps/ieee754/dbl-64/e_pow.c (__ieee754_pow): Do not return 1
+	for arguments (sNaN, 0) or (1, sNaN).  Do arithmetic on NaN
+	arguments to compute result.
+	* sysdeps/ieee754/flt-32/e_powf.c (__ieee754_powf): Do not return
+	1 for arguments (sNaN, 0) or (1, sNaN).
+	* sysdeps/ieee754/ldbl-128/e_powl.c (__ieee754_powl): Likewise.
+	* sysdeps/ieee754/ldbl-128ibm/e_powl.c (__ieee754_powl): Likewise.
+
 	[BZ #20919]
 	* sysdeps/ieee754/dbl-64/e_pow.c (__ieee754_pow): Do not return
 	NaN first argument when raised to power 0.
diff --git a/sysdeps/ieee754/dbl-64/e_pow.c b/sysdeps/ieee754/dbl-64/e_pow.c
index db6ecf76e5..8f9b1c02ba 100644
--- a/sysdeps/ieee754/dbl-64/e_pow.c
+++ b/sysdeps/ieee754/dbl-64/e_pow.c
@@ -74,8 +74,8 @@ __ieee754_pow (double x, double y)
       qx = u.i[HIGH_HALF] & 0x7fffffff;
       /* Is x a NaN?  */
       if ((((qx == 0x7ff00000) && (u.i[LOW_HALF] != 0)) || (qx > 0x7ff00000))
-	  && y != 0)
-	return x;
+	  && (y != 0 || issignaling (x)))
+	return x + x;
       if (y == 1.0)
 	return x;
       if (y == 2.0)
@@ -129,7 +129,7 @@ __ieee754_pow (double x, double y)
     {
       if (((v.i[HIGH_HALF] & 0x7fffffff) == 0x7ff00000 && v.i[LOW_HALF] != 0)
 	  || (v.i[HIGH_HALF] & 0x7fffffff) > 0x7ff00000)	/* NaN */
-	return y;
+	return y + y;
       if (fabs (y) > 1.0e20)
 	return (y > 0) ? 0 : 1.0 / 0.0;
       k = checkint (y);
@@ -143,9 +143,9 @@ __ieee754_pow (double x, double y)
   qy = v.i[HIGH_HALF] & 0x7fffffff;	/*   no sign   */
 
   if (qx >= 0x7ff00000 && (qx > 0x7ff00000 || u.i[LOW_HALF] != 0))	/* NaN */
-    return x;
+    return x + y;
   if (qy >= 0x7ff00000 && (qy > 0x7ff00000 || v.i[LOW_HALF] != 0))	/* NaN */
-    return x == 1.0 ? 1.0 : y;
+    return x == 1.0 && !issignaling (y) ? 1.0 : y + y;
 
   /* if x<0 */
   if (u.i[HIGH_HALF] < 0)
diff --git a/sysdeps/ieee754/flt-32/e_powf.c b/sysdeps/ieee754/flt-32/e_powf.c
index c72fe37d3b..d9470f190d 100644
--- a/sysdeps/ieee754/flt-32/e_powf.c
+++ b/sysdeps/ieee754/flt-32/e_powf.c
@@ -62,10 +62,10 @@ __ieee754_powf(float x, float y)
 	ix = hx&0x7fffffff;  iy = hy&0x7fffffff;
 
     /* y==zero: x**0 = 1 */
-	if(iy==0) return one;
+	if(iy==0 && !issignaling (x)) return one;
 
     /* x==+-1 */
-	if(x == 1.0) return one;
+	if(x == 1.0 && !issignaling (y)) return one;
 	if(x == -1.0 && isinf(y)) return one;
 
     /* +-NaN return x+y */
diff --git a/sysdeps/ieee754/ldbl-128/e_powl.c b/sysdeps/ieee754/ldbl-128/e_powl.c
index e6cd9751c2..a344840090 100644
--- a/sysdeps/ieee754/ldbl-128/e_powl.c
+++ b/sysdeps/ieee754/ldbl-128/e_powl.c
@@ -165,11 +165,12 @@ __ieee754_powl (_Float128 x, _Float128 y)
 
 
   /* y==zero: x**0 = 1 */
-  if ((iy | q.parts32.w1 | q.parts32.w2 | q.parts32.w3) == 0)
+  if ((iy | q.parts32.w1 | q.parts32.w2 | q.parts32.w3) == 0
+      && !issignaling (x))
     return one;
 
   /* 1.0**y = 1; -1.0**+-Inf = 1 */
-  if (x == one)
+  if (x == one && !issignaling (y))
     return one;
   if (x == -1 && iy == 0x7fff0000
       && (q.parts32.w1 | q.parts32.w2 | q.parts32.w3) == 0)
diff --git a/sysdeps/ieee754/ldbl-128ibm/e_powl.c b/sysdeps/ieee754/ldbl-128ibm/e_powl.c
index 861b44ac8b..d6fbef6997 100644
--- a/sysdeps/ieee754/ldbl-128ibm/e_powl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/e_powl.c
@@ -165,11 +165,11 @@ __ieee754_powl (long double x, long double y)
   iy = hy & 0x7fffffff;
 
   /* y==zero: x**0 = 1 */
-  if ((iy | ly) == 0)
+  if ((iy | ly) == 0 && !issignaling (x))
     return one;
 
   /* 1.0**y = 1; -1.0**+-Inf = 1 */
-  if (x == one)
+  if (x == one && !issignaling (y))
     return one;
   if (x == -1.0L && ((iy - 0x7ff00000) | ly) == 0)
     return one;