This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix x86/x86_64 nextafterl incrementing negative subnormals (bug 20205) [committed]


The x86 / x86_64 implementation of nextafterl (also used for
nexttowardl) produces incorrect results (NaNs) when negative
subnormals, the low 32 bits of whose mantissa are zero, are
incremented towards zero.  This patch fixes this by disabling the
logic to decrement the exponent in that case.

Tested for x86_64 and x86.  Committed.

2016-06-03  Joseph Myers  <joseph@codesourcery.com>

	[BZ #20205]
	* sysdeps/i386/fpu/s_nextafterl.c (__nextafterl): Do not adjust
	exponent when incrementing negative subnormal with low mantissa
	word zero.
	* math/libm-test.inc (nextafter_test_data) [TEST_COND_intel96]:
	Add another test.

diff --git a/math/libm-test.inc b/math/libm-test.inc
index 8c64c8e..aaa0148 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -9965,6 +9965,10 @@ static const struct test_ff_f_data nextafter_test_data[] =
     TEST_ff_f (nextafter, -min_subnorm_value, 0, minus_zero, INEXACT_EXCEPTION|UNDERFLOW_EXCEPTION|ERRNO_ERANGE),
     TEST_ff_f (nextafter, -min_subnorm_value, minus_zero, minus_zero, INEXACT_EXCEPTION|UNDERFLOW_EXCEPTION|ERRNO_ERANGE),
 
+#if TEST_COND_intel96
+    TEST_ff_f (nextafter, -0x0.fffffffep-16382L, 0.0L, -0x0.fffffffdfffffffep-16382L, INEXACT_EXCEPTION|UNDERFLOW_EXCEPTION|ERRNO_ERANGE),
+#endif
+
 #if MANT_DIG >= 64
     // XXX Enable once gcc is fixed.
     //TEST_ff_f (nextafter, 0x0.00000040000000000000p-16385L, -0.1L, 0x0.0000003ffffffff00000p-16385L),
diff --git a/sysdeps/i386/fpu/s_nextafterl.c b/sysdeps/i386/fpu/s_nextafterl.c
index 188dc21..600ad7a 100644
--- a/sysdeps/i386/fpu/s_nextafterl.c
+++ b/sysdeps/i386/fpu/s_nextafterl.c
@@ -86,7 +86,7 @@ long double __nextafterl(long double x, long double y)
 	    if(esy>=0||(esx>esy||((esx==esy)&&(hx>hy||((hx==hy)&&(lx>ly)))))){
 	      /* x < y, x -= ulp */
 		if(lx==0) {
-		    if (hx <= 0x80000000) {
+		    if (hx <= 0x80000000 && esx != 0xffff8000) {
 			esx -= 1;
 			hx = hx - 1;
 			if ((esx&0x7fff) > 0)

-- 
Joseph S. Myers
joseph@codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]