about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--NEWS12
-rw-r--r--math/libm-test.inc9
-rw-r--r--sysdeps/ieee754/k_standardl.c32
4 files changed, 35 insertions, 30 deletions
diff --git a/ChangeLog b/ChangeLog
index 6c18edd5c5..2f07bc101b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2015-06-23  Joseph Myers  <joseph@codesourcery.com>
+
+	[BZ #18245]
+	[BZ #18583]
+	* sysdeps/ieee754/k_standardl.c: Include <fenv.h>.
+	(__kernel_standard_l): Use feholdexcept and fesetenv around
+	conversion to double instead of special-casing overflow and
+	underflow.
+	* math/libm-test.inc (fmod_test_data): Add more tests.
+	(remainder_test_data): Likewise.
+	(sqrt_test_data): Likewise.
+
 2015-06-23  Torvald Riegel  <triegel@redhat.com>
 
 	[BZ #17403]
diff --git a/NEWS b/NEWS
index a46efd69bc..da4ed7e1fc 100644
--- a/NEWS
+++ b/NEWS
@@ -19,12 +19,12 @@ Version 2.22
   18032, 18034, 18036, 18038, 18039, 18042, 18043, 18046, 18047, 18049,
   18068, 18080, 18093, 18100, 18104, 18110, 18111, 18116, 18125, 18128,
   18138, 18185, 18196, 18197, 18206, 18210, 18211, 18217, 18219, 18220,
-  18221, 18234, 18244, 18247, 18287, 18319, 18324, 18333, 18346, 18371,
-  18397, 18409, 18410, 18412, 18418, 18422, 18434, 18444, 18468, 18469,
-  18470, 18479, 18483, 18495, 18496, 18497, 18498, 18507, 18512, 18513,
-  18519, 18520, 18522, 18527, 18528, 18529, 18530, 18532, 18533, 18534,
-  18536, 18539, 18540, 18542, 18544, 18545, 18546, 18547, 18553, 18558,
-  18569.
+  18221, 18234, 18244, 18245, 18247, 18287, 18319, 18324, 18333, 18346,
+  18371, 18397, 18409, 18410, 18412, 18418, 18422, 18434, 18444, 18468,
+  18469, 18470, 18479, 18483, 18495, 18496, 18497, 18498, 18507, 18512,
+  18513, 18519, 18520, 18522, 18527, 18528, 18529, 18530, 18532, 18533,
+  18534, 18536, 18539, 18540, 18542, 18544, 18545, 18546, 18547, 18553,
+  18558, 18569, 18583.
 
 * Cache information can be queried via sysconf() function on s390 e.g. with
   _SC_LEVEL1_ICACHE_SIZE as argument.
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 85a1746876..03c3831389 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -7115,12 +7115,16 @@ static const struct test_ff_f_data fmod_test_data[] =
 
     /* fmod (+inf, y) == qNaN plus invalid exception.  */
     TEST_ff_f (fmod, plus_infty, 3, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_ff_f (fmod, plus_infty, -1.1L, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
     /* fmod (-inf, y) == qNaN plus invalid exception.  */
     TEST_ff_f (fmod, minus_infty, 3, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_ff_f (fmod, minus_infty, -1.1L, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
     /* fmod (x, +0) == qNaN plus invalid exception.  */
     TEST_ff_f (fmod, 3, 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_ff_f (fmod, -1.1L, 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
     /* fmod (x, -0) == qNaN plus invalid exception.  */
     TEST_ff_f (fmod, 3, minus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_ff_f (fmod, -1.1L, minus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
 
     /* fmod (x, +inf) == x for x not infinite.  */
     TEST_ff_f (fmod, 3.0, plus_infty, 3.0, NO_INEXACT_EXCEPTION),
@@ -8719,6 +8723,8 @@ static const struct test_ff_f_data remainder_test_data[] =
   {
     TEST_ff_f (remainder, 1, 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
     TEST_ff_f (remainder, 1, minus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_ff_f (remainder, -1.1L, 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_ff_f (remainder, -1.1L, minus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
     TEST_ff_f (remainder, plus_zero, plus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
     TEST_ff_f (remainder, plus_zero, minus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
     TEST_ff_f (remainder, minus_zero, plus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
@@ -8726,12 +8732,14 @@ static const struct test_ff_f_data remainder_test_data[] =
     TEST_ff_f (remainder, plus_infty, minus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
     TEST_ff_f (remainder, plus_infty, 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
     TEST_ff_f (remainder, plus_infty, 1, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_ff_f (remainder, plus_infty, 1.1L, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
     TEST_ff_f (remainder, plus_infty, 2, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
     TEST_ff_f (remainder, plus_infty, plus_infty, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
     TEST_ff_f (remainder, plus_infty, minus_infty, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
     TEST_ff_f (remainder, minus_infty, minus_zero, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
     TEST_ff_f (remainder, minus_infty, 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
     TEST_ff_f (remainder, minus_infty, 1, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_ff_f (remainder, minus_infty, 1.1L, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
     TEST_ff_f (remainder, minus_infty, 2, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
     TEST_ff_f (remainder, minus_infty, plus_infty, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
     TEST_ff_f (remainder, minus_infty, minus_infty, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
@@ -9507,6 +9515,7 @@ static const struct test_f_f_data sqrt_test_data[] =
 
     /* sqrt (x) == qNaN plus invalid exception for x < 0.  */
     TEST_f_f (sqrt, -1, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_f_f (sqrt, -1.1L, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
     TEST_f_f (sqrt, -max_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
     TEST_f_f (sqrt, minus_infty, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
 
diff --git a/sysdeps/ieee754/k_standardl.c b/sysdeps/ieee754/k_standardl.c
index eaa2f661f1..aa95748825 100644
--- a/sysdeps/ieee754/k_standardl.c
+++ b/sysdeps/ieee754/k_standardl.c
@@ -32,6 +32,7 @@
 
 #include <math.h>
 #include <math_private.h>
+#include <fenv.h>
 #include <float.h>
 #include <errno.h>
 
@@ -47,31 +48,14 @@ __kernel_standard_l (long double x, long double y, int type)
 {
   double dx, dy;
   struct exception exc;
+  fenv_t env;
 
-  if (isfinite (x))
-    {
-      long double ax = fabsl (x);
-      if (ax > DBL_MAX)
-	dx = __copysignl (DBL_MAX, x);
-      else if (ax > 0 && ax < DBL_MIN)
-	dx = __copysignl (DBL_MIN, x);
-      else
-	dx = x;
-    }
-  else
-    dx = x;
-  if (isfinite (y))
-    {
-      long double ay = fabsl (y);
-      if (ay > DBL_MAX)
-	dy = __copysignl (DBL_MAX, y);
-      else if (ay > 0 && ay < DBL_MIN)
-	dy = __copysignl (DBL_MIN, y);
-      else
-	dy = y;
-    }
-  else
-    dy = y;
+  feholdexcept (&env);
+  dx = x;
+  dy = y;
+  math_force_eval (dx);
+  math_force_eval (dy);
+  fesetenv (&env);
 
   switch (type)
     {