about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2015-09-30 21:44:42 +0000
committerJoseph Myers <joseph@codesourcery.com>2015-09-30 21:44:42 +0000
commit8c6c9236361fbc077769673c259828216403bc33 (patch)
tree04b02cf33c6654bc380d2c2ef986c41c4166d2ee
parent93e448cbed1095c88133f2a304b1bbba72e480af (diff)
downloadglibc-8c6c9236361fbc077769673c259828216403bc33.tar.gz
glibc-8c6c9236361fbc077769673c259828216403bc33.tar.xz
glibc-8c6c9236361fbc077769673c259828216403bc33.zip
Fix i386 acosh (-qNaN) spurious "invalid" exception.
The i386 versions of acoshf and acosh raise a spurious "invalid"
exception for an argument that is a quiet NaN with the sign bit set.
The integer arithmetic to detect arguments < 1 also detects -NaN, and
then the computation 0 / 0 in that case raises the exception.  This
patch fixes this by using (x - x) / (x - x) as the computation in that
case instead, which will always raise the exception for non-NaN
arguments reaching that code, but not for quiet NaN arguments.

Tested for x86_64 and x86.

	[BZ #19032]
	* sysdeps/i386/fpu/e_acosh.S (__ieee754_acosh): For arguments < 1,
	compute result as (x - x) / (x - x) not as 0 / 0.
	* sysdeps/i386/fpu/e_acoshf.S (__ieee754_acoshf): Likewise.
	* math/libm-test.inc (acosh_test_data): Add another test of acosh.
-rw-r--r--ChangeLog6
-rw-r--r--NEWS2
-rw-r--r--math/libm-test.inc1
-rw-r--r--sysdeps/i386/fpu/e_acosh.S5
-rw-r--r--sysdeps/i386/fpu/e_acoshf.S5
5 files changed, 14 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index ea038f764f..958b4a3a9d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2015-09-30  Joseph Myers  <joseph@codesourcery.com>
 
+	[BZ #19032]
+	* sysdeps/i386/fpu/e_acosh.S (__ieee754_acosh): For arguments < 1,
+	compute result as (x - x) / (x - x) not as 0 / 0.
+	* sysdeps/i386/fpu/e_acoshf.S (__ieee754_acoshf): Likewise.
+	* math/libm-test.inc (acosh_test_data): Add another test of acosh.
+
 	* math/auto-libm-test-in: Add more tests of acos, acosh, asin,
 	atan, atan2, atanh, cbrt, cos, cosh, erf, erfc, exp, exp10, exp2
 	and expm1.
diff --git a/NEWS b/NEWS
index ea64dc7c40..e7e11bf987 100644
--- a/NEWS
+++ b/NEWS
@@ -17,7 +17,7 @@ Version 2.23
   18789, 18790, 18795, 18796, 18803, 18820, 18823, 18824, 18825, 18857,
   18863, 18870, 18872, 18873, 18875, 18887, 18921, 18951, 18952, 18956,
   18961, 18966, 18967, 18969, 18970, 18977, 18980, 18981, 18985, 19003,
-  19016.
+  19016, 19032.
 
 * The obsolete header <regexp.h> has been removed.  Programs that require
   this header must be updated to use <regex.h> instead.
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 744c66dbb1..8615957600 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -1790,6 +1790,7 @@ static const struct test_f_f_data acosh_test_data[] =
     TEST_f_f (acosh, plus_infty, plus_infty, ERRNO_UNCHANGED),
     TEST_f_f (acosh, minus_infty, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
     TEST_f_f (acosh, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (acosh, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 
     /* x < 1:  */
     TEST_f_f (acosh, 0.75L, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
diff --git a/sysdeps/i386/fpu/e_acosh.S b/sysdeps/i386/fpu/e_acosh.S
index c5cd4474ec..263c01a4ed 100644
--- a/sysdeps/i386/fpu/e_acosh.S
+++ b/sysdeps/i386/fpu/e_acosh.S
@@ -91,9 +91,10 @@ ENTRY(__ieee754_acosh)
 	fyl2x				// log(2*x+1/(x+sqrt(x^2-1)))
 	ret
 
-	// x < 1 => NaN
+	// x < 1 (or -NaN) => NaN
 	.align ALIGNARG(4)
-5:	fldz
+5:	fldl	4(%esp)
+	fsub	%st
 	fdiv	%st, %st(0)
 	ret
 END(__ieee754_acosh)
diff --git a/sysdeps/i386/fpu/e_acoshf.S b/sysdeps/i386/fpu/e_acoshf.S
index 710267b11e..779a02cfab 100644
--- a/sysdeps/i386/fpu/e_acoshf.S
+++ b/sysdeps/i386/fpu/e_acoshf.S
@@ -91,9 +91,10 @@ ENTRY(__ieee754_acoshf)
 	fyl2x				// log(2*x+1/(x+sqrt(x^2-1)))
 	ret
 
-	// x < 1 => NaN
+	// x < 1 (or -NaN) => NaN
 	.align ALIGNARG(4)
-5:	fldz
+5:	flds	4(%esp)
+	fsub	%st
 	fdiv	%st, %st(0)
 	ret
 END(__ieee754_acoshf)