about summary refs log tree commit diff
path: root/sysdeps/i386
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2015-10-02 17:11:13 +0000
committerJoseph Myers <joseph@codesourcery.com>2015-10-02 17:11:13 +0000
commit59a63cca1133a8e1e3219970ee95979ac1f810df (patch)
treea4fc7c389f60647377479748d75bcc94f3c36547 /sysdeps/i386
parentef6b619f73e49b6d87c7530e6e9f8a59723b492d (diff)
downloadglibc-59a63cca1133a8e1e3219970ee95979ac1f810df.tar.gz
glibc-59a63cca1133a8e1e3219970ee95979ac1f810df.tar.xz
glibc-59a63cca1133a8e1e3219970ee95979ac1f810df.zip
Fix nexttoward overflow in non-default rounding modes (bug 19059).
ISO C requires overflowing results from nexttoward to be the
appropriate infinity independent of the rounding mode, but some
implementations use a rounding-mode-dependent result (this is the same
issue as was fixed for nextafter in bug 16677).  This patch fixes the
problem by making the nexttoward implementations discard the result
from the floating-point computation that forced an overflow exception
and then return the infinity previously computed with integer
arithmetic.

Tested for x86_64, x86, mips64 and powerpc.

	[BZ #19059]
	* math/s_nexttowardf.c (__nexttowardf): Do not return value from
	overflowing computation.
	* sysdeps/i386/fpu/s_nexttoward.c (__nexttoward): Likewise.
	* sysdeps/i386/fpu/s_nexttowardf.c (__nexttowardf): Likewise.
	* sysdeps/ieee754/ldbl-128/s_nexttoward.c (__nexttoward):
	Likewise.
	* sysdeps/ieee754/ldbl-128/s_nexttowardf.c (__nexttowardf):
	Likewise.
	* sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c (__nexttoward):
	Likewise.
	* sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c (__nexttowardf):
	Likewise.
	* sysdeps/ieee754/ldbl-96/s_nexttoward.c (__nexttoward): Likewise.
	* sysdeps/ieee754/ldbl-96/s_nexttowardf.c (__nexttowardf):
	Likewise.
	* sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c (__nldbl_nexttowardf):
	Likewise.
	* math/libm-test.inc (nexttoward_test_data): Add more tests.
Diffstat (limited to 'sysdeps/i386')
-rw-r--r--sysdeps/i386/fpu/s_nexttoward.c4
-rw-r--r--sysdeps/i386/fpu/s_nexttowardf.c4
2 files changed, 4 insertions, 4 deletions
diff --git a/sysdeps/i386/fpu/s_nexttoward.c b/sysdeps/i386/fpu/s_nexttoward.c
index be65b8ce29..839efe6c05 100644
--- a/sysdeps/i386/fpu/s_nexttoward.c
+++ b/sysdeps/i386/fpu/s_nexttoward.c
@@ -73,8 +73,8 @@ double __nexttoward(double x, long double y)
 	}
 	hy = hx&0x7ff00000;
 	if(hy>=0x7ff00000) {
-	  x = math_narrow_eval (x+x);	/* overflow  */
-	  return x;
+	  double u = x+x;			/* overflow  */
+	  math_force_eval (u);
 	}
 	if(hy<0x00100000) {
 	    double u = x*x;			/* underflow */
diff --git a/sysdeps/i386/fpu/s_nexttowardf.c b/sysdeps/i386/fpu/s_nexttowardf.c
index 8379eff8b8..29b4f12775 100644
--- a/sysdeps/i386/fpu/s_nexttowardf.c
+++ b/sysdeps/i386/fpu/s_nexttowardf.c
@@ -61,8 +61,8 @@ float __nexttowardf(float x, long double y)
 	}
 	hy = hx&0x7f800000;
 	if(hy>=0x7f800000) {
-	  x = math_narrow_eval (x+x);	/* overflow  */
-	  return x;
+	  float u = x+x;			/* overflow  */
+	  math_force_eval (u);
 	}
 	if(hy<0x00800000) {
 	    float u = x*x;			/* underflow */