about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2016-06-13 21:43:22 +0000
committerJoseph Myers <joseph@codesourcery.com>2016-06-13 21:43:22 +0000
commita2ae1696f7c6cf269b3a734bce4d9d3620745854 (patch)
tree92c9bed2652bb67d71de2c930613dd350776b6d4
parent5e19c4347f484d5f5b44bf8317b38f8f2fd564c1 (diff)
downloadglibc-a2ae1696f7c6cf269b3a734bce4d9d3620745854.tar.gz
glibc-a2ae1696f7c6cf269b3a734bce4d9d3620745854.tar.xz
glibc-a2ae1696f7c6cf269b3a734bce4d9d3620745854.zip
Fix dbl-64 atan2 (sNaN, qNaN) (bug 20252).
The dbl-64 implementation of atan2, passed arguments (sNaN, qNaN),
fails to raise the "invalid" exception.  This patch fixes it to add
both arguments, rather than just adding the second argument to itself,
in the case where the second argument is a NaN (which is checked for
before checking for the first argument being a NaN).  sNaN tests for
atan2 are added, along with some qNaN tests I noticed were missing but
should have been there by analogy with other tests present.

Tested for x86_64 and x86.

	[BZ #20252]
	* sysdeps/ieee754/dbl-64/e_atan2.c (__ieee754_atan2): Add both
	arguments when second argument is a NaN.
	* math/libm-test.inc (atan2_test_data): Add sNaN tests and more
	qNaN tests.
-rw-r--r--ChangeLog6
-rw-r--r--math/libm-test.inc62
-rw-r--r--sysdeps/ieee754/dbl-64/e_atan2.c2
3 files changed, 69 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index d6b12ff917..1d2c3e3d86 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2016-06-13  Joseph Myers  <joseph@codesourcery.com>
 
+	[BZ #20252]
+	* sysdeps/ieee754/dbl-64/e_atan2.c (__ieee754_atan2): Add both
+	arguments when second argument is a NaN.
+	* math/libm-test.inc (atan2_test_data): Add sNaN tests and more
+	qNaN tests.
+
 	* math/libm-test.inc (cimag_test_data): Add sNaN tests.
 	(conj_test_data): Likewise.
 	(copysign_test_data): Likewise.
diff --git a/math/libm-test.inc b/math/libm-test.inc
index a8414ec9ca..010743f98c 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -1986,6 +1986,18 @@ static const struct test_ff_f_data atan2_test_data[] =
     TEST_ff_f (atan2, qnan_value, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_ff_f (atan2, -qnan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_ff_f (atan2, -qnan_value, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_ff_f (atan2, snan_value, qnan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, snan_value, -qnan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -snan_value, qnan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -snan_value, -qnan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, qnan_value, snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, qnan_value, -snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -qnan_value, snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -qnan_value, -snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, snan_value, snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, snan_value, -snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -snan_value, snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -snan_value, -snan_value, qnan_value, INVALID_EXCEPTION),
     TEST_ff_f (atan2, qnan_value, plus_infty, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_ff_f (atan2, qnan_value, minus_infty, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_ff_f (atan2, qnan_value, plus_zero, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
@@ -2010,6 +2022,30 @@ static const struct test_ff_f_data atan2_test_data[] =
     TEST_ff_f (atan2, -qnan_value, -min_subnorm_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_ff_f (atan2, -qnan_value, max_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_ff_f (atan2, -qnan_value, -max_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_ff_f (atan2, snan_value, plus_infty, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, snan_value, minus_infty, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, snan_value, plus_zero, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, snan_value, minus_zero, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, snan_value, 1, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, snan_value, -1, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, snan_value, min_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, snan_value, -min_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, snan_value, min_subnorm_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, snan_value, -min_subnorm_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, snan_value, max_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, snan_value, -max_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -snan_value, plus_infty, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -snan_value, minus_infty, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -snan_value, plus_zero, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -snan_value, minus_zero, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -snan_value, 1, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -snan_value, -1, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -snan_value, min_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -snan_value, -min_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -snan_value, min_subnorm_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -snan_value, -min_subnorm_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -snan_value, max_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -snan_value, -max_value, qnan_value, INVALID_EXCEPTION),
     TEST_ff_f (atan2, plus_infty, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_ff_f (atan2, minus_infty, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_ff_f (atan2, plus_zero, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
@@ -2022,6 +2058,8 @@ static const struct test_ff_f_data atan2_test_data[] =
     TEST_ff_f (atan2, -min_subnorm_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_ff_f (atan2, max_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_ff_f (atan2, -max_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_ff_f (atan2, plus_infty, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_ff_f (atan2, minus_infty, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_ff_f (atan2, plus_zero, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_ff_f (atan2, minus_zero, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_ff_f (atan2, 1, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
@@ -2032,6 +2070,30 @@ static const struct test_ff_f_data atan2_test_data[] =
     TEST_ff_f (atan2, -min_subnorm_value, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_ff_f (atan2, max_value, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_ff_f (atan2, -max_value, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_ff_f (atan2, plus_infty, snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, minus_infty, snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, plus_zero, snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, minus_zero, snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, 1, snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -1, snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, min_value, snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -min_value, snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, min_subnorm_value, snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -min_subnorm_value, snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, max_value, snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -max_value, snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, plus_infty, -snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, minus_infty, -snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, plus_zero, -snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, minus_zero, -snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, 1, -snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -1, -snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, min_value, -snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -min_value, -snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, min_subnorm_value, -snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -min_subnorm_value, -snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, max_value, -snan_value, qnan_value, INVALID_EXCEPTION),
+    TEST_ff_f (atan2, -max_value, -snan_value, qnan_value, INVALID_EXCEPTION),
 
     AUTO_TESTS_ff_f (atan2),
   };
diff --git a/sysdeps/ieee754/dbl-64/e_atan2.c b/sysdeps/ieee754/dbl-64/e_atan2.c
index 22e8fb8fef..0838907019 100644
--- a/sysdeps/ieee754/dbl-64/e_atan2.c
+++ b/sysdeps/ieee754/dbl-64/e_atan2.c
@@ -91,7 +91,7 @@ __ieee754_atan2 (double y, double x)
   if ((ux & 0x7ff00000) == 0x7ff00000)
     {
       if (((ux & 0x000fffff) | dx) != 0x00000000)
-	return x + x;
+	return x + y;
     }
   num.d = y;
   uy = num.i[HIGH_HALF];