Test signs of NaNs in libm-test.inc where appropriate.
authorJoseph Myers <joseph@codesourcery.com>
Sat, 16 Nov 2013 12:48:35 +0000 (12:48 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Sat, 16 Nov 2013 12:48:35 +0000 (12:48 +0000)
ChangeLog
math/gen-libm-test.pl
math/libm-test.inc

index 96c22ba..7e543af 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,22 @@
 2013-11-16  Joseph Myers  <joseph@codesourcery.com>
 
+       * math/libm-test.inc (TEST_NAN_SIGN): New macro.
+       (NO_TEST_INLINE): Update value.
+       (ERRNO_UNCHANGED): Likewise.
+       (ERRNO_EDOM): Likewise.
+       (ERRNO_ERANGE): Likewise.
+       (IGNORE_RESULT): Likewise.
+       (check_float_internal): Check signs of NaN results if
+       TEST_NAN_SIGN used.
+       (check_complex): Pass TEST_NAN_SIGN flag through to second
+       check_float_internal call.
+       (copysign_test_data): Add tests with quiet NaNs as second
+       argument.  Use TEST_NAN_SIGN.
+       (fabs_test_data): Add test of negative quiet NaN argument.  Use
+       TEST_NAN_SIGN.
+       (signbit_test_data): Add tests of quiet NaN argument.
+       * math/gen-libm-test.pl (parse_args): Handle TEST_NAN_SIGN.
+
        * math/gen-libm-test.pl (show_exceptions): Take extra argument
        $ignore_result.
        (parse_args): Handle function results specified as IGNORE.
index 98112ed..bd701d7 100755 (executable)
@@ -218,7 +218,7 @@ sub parse_args {
   # consistency check
   if ($current_arg == $#args) {
     die ("wrong number of arguments")
-      unless ($args[$current_arg] =~ /EXCEPTION|ERRNO|IGNORE_ZERO_INF_SIGN|NO_TEST_INLINE/);
+      unless ($args[$current_arg] =~ /EXCEPTION|ERRNO|IGNORE_ZERO_INF_SIGN|TEST_NAN_SIGN|NO_TEST_INLINE/);
   } elsif ($current_arg < $#args) {
     die ("wrong number of arguments");
   } elsif ($current_arg > ($#args+1)) {
index 790fcc8..0c88abc 100644 (file)
@@ -173,13 +173,14 @@ struct ulp_data
 #define EXCEPTIONS_OK INVALID_EXCEPTION_OK+DIVIDE_BY_ZERO_EXCEPTION_OK
 /* Some special test flags, passed together with exceptions.  */
 #define IGNORE_ZERO_INF_SIGN           0x400
-#define NO_TEST_INLINE                 0x800
+#define TEST_NAN_SIGN                  0x800
+#define NO_TEST_INLINE                 0x1000
 /* Indicate errno settings required or disallowed.  */
-#define ERRNO_UNCHANGED                        0x1000
-#define ERRNO_EDOM                     0x2000
-#define ERRNO_ERANGE                   0x4000
+#define ERRNO_UNCHANGED                        0x2000
+#define ERRNO_EDOM                     0x4000
+#define ERRNO_ERANGE                   0x8000
 /* Flags generated by gen-libm-test.pl, not entered here manually.  */
-#define IGNORE_RESULT                  0x8000
+#define IGNORE_RESULT                  0x10000
 
 /* Values underflowing only for float.  */
 #ifdef TEST_FLOAT
@@ -732,11 +733,29 @@ check_float_internal (const char *test_name, FLOAT computed, FLOAT expected,
     goto out;
   FLOAT max_ulp = find_test_ulps (test_name);
   if (issignaling (computed) && issignaling (expected))
-    ok = 1;
+    {
+      if ((exceptions & TEST_NAN_SIGN) != 0
+         && signbit (computed) != signbit (expected))
+       {
+         ok = 0;
+         printf ("signaling NaN has wrong sign.\n");
+       }
+      else
+       ok = 1;
+    }
   else if (issignaling (computed) || issignaling (expected))
     ok = 0;
   else if (isnan (computed) && isnan (expected))
-    ok = 1;
+    {
+      if ((exceptions & TEST_NAN_SIGN) != 0
+         && signbit (computed) != signbit (expected))
+       {
+         ok = 0;
+         printf ("quiet NaN has wrong sign.\n");
+       }
+      else
+       ok = 1;
+    }
   else if (isinf (computed) && isinf (expected))
     {
       /* Test for sign of infinities.  */
@@ -834,7 +853,9 @@ check_complex (const char *test_name, __complex__ FLOAT computed,
   /* Don't check again for exceptions or errno, just pass through the
      other relevant flags.  */
   check_float_internal (str, part_comp, part_exp,
-                       exception & (IGNORE_ZERO_INF_SIGN | IGNORE_RESULT),
+                       exception & (IGNORE_ZERO_INF_SIGN
+                                    | TEST_NAN_SIGN
+                                    | IGNORE_RESULT),
                        &imag_max_error);
   free (str);
 }
@@ -6815,11 +6836,15 @@ static const struct test_ff_f_data copysign_test_data[] =
     TEST_ff_f (copysign, minus_zero, plus_infty, 0, NO_INEXACT_EXCEPTION),
     TEST_ff_f (copysign, minus_zero, minus_zero, minus_zero, NO_INEXACT_EXCEPTION),
 
-    /* XXX More correctly we would have to check the sign of the NaN.  */
-    TEST_ff_f (copysign, qnan_value, 0, qnan_value, NO_INEXACT_EXCEPTION),
-    TEST_ff_f (copysign, qnan_value, minus_zero, qnan_value, NO_INEXACT_EXCEPTION),
-    TEST_ff_f (copysign, -qnan_value, 0, qnan_value, NO_INEXACT_EXCEPTION),
-    TEST_ff_f (copysign, -qnan_value, minus_zero, qnan_value, NO_INEXACT_EXCEPTION),
+    TEST_ff_f (copysign, 0, qnan_value, 0, NO_INEXACT_EXCEPTION),
+    TEST_ff_f (copysign, 0, -qnan_value, minus_zero, NO_INEXACT_EXCEPTION),
+    TEST_ff_f (copysign, minus_zero, qnan_value, 0, NO_INEXACT_EXCEPTION),
+    TEST_ff_f (copysign, minus_zero, -qnan_value, minus_zero, NO_INEXACT_EXCEPTION),
+
+    TEST_ff_f (copysign, qnan_value, 0, qnan_value, NO_INEXACT_EXCEPTION|TEST_NAN_SIGN),
+    TEST_ff_f (copysign, qnan_value, minus_zero, -qnan_value, NO_INEXACT_EXCEPTION|TEST_NAN_SIGN),
+    TEST_ff_f (copysign, -qnan_value, 0, qnan_value, NO_INEXACT_EXCEPTION|TEST_NAN_SIGN),
+    TEST_ff_f (copysign, -qnan_value, minus_zero, -qnan_value, NO_INEXACT_EXCEPTION|TEST_NAN_SIGN),
   };
 
 static void
@@ -8196,7 +8221,8 @@ static const struct test_f_f_data fabs_test_data[] =
 
     TEST_f_f (fabs, plus_infty, plus_infty, NO_INEXACT_EXCEPTION),
     TEST_f_f (fabs, minus_infty, plus_infty, NO_INEXACT_EXCEPTION),
-    TEST_f_f (fabs, qnan_value, qnan_value, NO_INEXACT_EXCEPTION),
+    TEST_f_f (fabs, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|TEST_NAN_SIGN),
+    TEST_f_f (fabs, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|TEST_NAN_SIGN),
 
     TEST_f_f (fabs, 38.0, 38.0, NO_INEXACT_EXCEPTION),
     TEST_f_f (fabs, -M_El, M_El, NO_INEXACT_EXCEPTION),
@@ -13347,11 +13373,12 @@ scalbln_test (void)
 
 static const struct test_f_i_data signbit_test_data[] =
   {
-    /* TODO: missing qNaN tests.  */
     TEST_f_b (signbit, 0, 0, NO_INEXACT_EXCEPTION),
     TEST_f_b (signbit, minus_zero, 1, NO_INEXACT_EXCEPTION),
     TEST_f_b (signbit, plus_infty, 0, NO_INEXACT_EXCEPTION),
     TEST_f_b (signbit, minus_infty, 1, NO_INEXACT_EXCEPTION),
+    TEST_f_b (signbit, qnan_value, 0, NO_INEXACT_EXCEPTION),
+    TEST_f_b (signbit, -qnan_value, 1, NO_INEXACT_EXCEPTION),
 
     /* signbit (x) != 0 for x < 0.  */
     TEST_f_b (signbit, -1, 1, NO_INEXACT_EXCEPTION),