about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2016-06-08 21:55:06 +0000
committerJoseph Myers <joseph@codesourcery.com>2016-06-08 21:55:06 +0000
commit9bd3ef8e19b19fb3cfcf99a33a1493035891b990 (patch)
treeca830d25692074e5b5800ee2f530a2d314fa2a0b
parent9946e7a949d3b0f2795d930aa2f2ce7bda5e4f8a (diff)
downloadglibc-9bd3ef8e19b19fb3cfcf99a33a1493035891b990.tar.gz
glibc-9bd3ef8e19b19fb3cfcf99a33a1493035891b990.tar.xz
glibc-9bd3ef8e19b19fb3cfcf99a33a1493035891b990.zip
Fix i386/x86_64 expl, exp10l, expm1l for sNaN input (bug 20226).
The i386 and x86_64 implementations of expl, exp10l and expm1l (code
shared between the functions) return sNaN for sNaN input.  This patch
fixes them to add NaN inputs to themselves so that qNaN is returned in
this case.

Tested for x86_64 and x86.

	[BZ #20226]
	* sysdeps/i386/fpu/e_expl.S (IEEE754_EXPL): Add NaN argument to
	itself.
	* sysdeps/x86_64/fpu/e_expl.S (IEEE754_EXPL): Likewise.
	* math/libm-test.inc (exp_test_data): Add sNaN tests.
	(exp10_test_data): Likewise.
	(expm1_test_data): Likewise.
-rw-r--r--ChangeLog8
-rw-r--r--math/libm-test.inc6
-rw-r--r--sysdeps/i386/fpu/e_expl.S7
-rw-r--r--sysdeps/x86_64/fpu/e_expl.S7
4 files changed, 24 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index cf5e480bbf..0d140aab66 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2016-06-08  Joseph Myers  <joseph@codesourcery.com>
 
+	[BZ #20226]
+	* sysdeps/i386/fpu/e_expl.S (IEEE754_EXPL): Add NaN argument to
+	itself.
+	* sysdeps/x86_64/fpu/e_expl.S (IEEE754_EXPL): Likewise.
+	* math/libm-test.inc (exp_test_data): Add sNaN tests.
+	(exp10_test_data): Likewise.
+	(expm1_test_data): Likewise.
+
 	[BZ #20225]
 	* math/s_ldexp.c (__ldexp): Add non-finite or zero argument to
 	itself.
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 583c27cfc0..35a256c485 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -6992,6 +6992,8 @@ static const struct test_f_f_data exp_test_data[] =
     TEST_f_f (exp, minus_infty, 0, ERRNO_UNCHANGED|NO_TEST_INLINE),
     TEST_f_f (exp, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (exp, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (exp, snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_f_f (exp, -snan_value, qnan_value, INVALID_EXCEPTION),
 
     AUTO_TESTS_f_f (exp),
   };
@@ -7009,6 +7011,8 @@ static const struct test_f_f_data exp10_test_data[] =
     TEST_f_f (exp10, minus_infty, 0, ERRNO_UNCHANGED),
     TEST_f_f (exp10, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (exp10, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (exp10, snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_f_f (exp10, -snan_value, qnan_value, INVALID_EXCEPTION),
 
     AUTO_TESTS_f_f (exp10),
   };
@@ -7052,6 +7056,8 @@ static const struct test_f_f_data expm1_test_data[] =
     TEST_f_f (expm1, minus_infty, -1, ERRNO_UNCHANGED|NO_TEST_INLINE),
     TEST_f_f (expm1, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (expm1, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (expm1, snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_f_f (expm1, -snan_value, qnan_value, INVALID_EXCEPTION),
 
     AUTO_TESTS_f_f (expm1),
   };
diff --git a/sysdeps/i386/fpu/e_expl.S b/sysdeps/i386/fpu/e_expl.S
index 64e0d96839..7d75fe22a1 100644
--- a/sysdeps/i386/fpu/e_expl.S
+++ b/sysdeps/i386/fpu/e_expl.S
@@ -102,7 +102,7 @@ ENTRY(IEEE754_EXPL)
 	/* Below -64.0 (may be -NaN or -Inf). */
 	andb	%ah, %dh
 	cmpb	$0x01, %dh
-	je	2f		/* Is +-NaN, jump.  */
+	je	6f		/* Is +-NaN, jump.  */
 	jmp	1f		/* -large, possibly -Inf.  */
 
 4:	/* In range -64.0 to 64.0 (may be +-0 but not NaN or +-Inf).  */
@@ -144,7 +144,7 @@ ENTRY(IEEE754_EXPL)
 	cmpb	$0x05, %dh
 	je	1f		/* Is +-Inf, jump.    */
 	cmpb	$0x01, %dh
-	je	2f		/* Is +-NaN, jump.    */
+	je	6f		/* Is +-NaN, jump.    */
 	/* Overflow or underflow; saturate.  */
 	fstp	%st
 	fldt	MO(csat)
@@ -214,6 +214,9 @@ ENTRY(IEEE754_EXPL)
 	fldz			/* Set result to 0.  */
 #endif
 2:	ret
+6:	/* NaN argument.  */
+	fadd	%st
+	ret
 END(IEEE754_EXPL)
 #ifdef USE_AS_EXPM1L
 libm_hidden_def (__expm1l)
diff --git a/sysdeps/x86_64/fpu/e_expl.S b/sysdeps/x86_64/fpu/e_expl.S
index 8b3ddaec59..a4ef023b2b 100644
--- a/sysdeps/x86_64/fpu/e_expl.S
+++ b/sysdeps/x86_64/fpu/e_expl.S
@@ -99,7 +99,7 @@ ENTRY(IEEE754_EXPL)
 	/* Below -64.0 (may be -NaN or -Inf). */
 	andb	%ah, %dh
 	cmpb	$0x01, %dh
-	je	2f		/* Is +-NaN, jump.  */
+	je	6f		/* Is +-NaN, jump.  */
 	jmp	1f		/* -large, possibly -Inf.  */
 
 4:	/* In range -64.0 to 64.0 (may be +-0 but not NaN or +-Inf).  */
@@ -141,7 +141,7 @@ ENTRY(IEEE754_EXPL)
 	cmpb	$0x05, %dh
 	je	1f		/* Is +-Inf, jump.    */
 	cmpb	$0x01, %dh
-	je	2f		/* Is +-NaN, jump.    */
+	je	6f		/* Is +-NaN, jump.    */
 	/* Overflow or underflow; saturate.  */
 	fstp	%st
 	fldt	MO(csat)
@@ -207,6 +207,9 @@ ENTRY(IEEE754_EXPL)
 	fldz			/* Set result to 0.  */
 #endif
 2:	ret
+6:	/* NaN argument.  */
+	fadd	%st
+	ret
 END(IEEE754_EXPL)
 #ifdef USE_AS_EXPM1L
 libm_hidden_def (__expm1l)