public inbox for libc-ports@sourceware.org
 help / color / mirror / Atom feed
* [attention machine maintainers] [PATCH] <math.h> issignaling
       [not found] <8762148l9v.fsf@schwinge.name>
@ 2013-03-22 11:18 ` Thomas Schwinge
  2013-03-24 21:30   ` David Miller
                     ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Thomas Schwinge @ 2013-03-22 11:18 UTC (permalink / raw)
  To: libc-alpha, libc-ports

[-- Attachment #1: Type: text/plain, Size: 47853 bytes --]

Hi!

On Wed, 06 Mar 2013 18:56:28 +0100, I wrote:
> In IEEE 754-1985, »Annex A Recommended Functions and Predicates«, 10) a
> function to distinguish signaling from quiet NaNs is suggested.  This is
> further elaborated in IEEE 754-2008, »5.7.2 General operations« as a
> isSignaling operation.  Such a macro/function is not yet part of any
> published revision of the C programming language standard, but has been
> under discussion for some time alreay, see for example in
> <http://www.open-std.org/jtc1/sc22/wg14/www/docs/PostPortland2012.htm>'s
> N1664 (the latest of its kind that is publically available, as far as I
> know), »14.7 Inquiry macros [...] Suggested change to C11: [...] 7.12.3.7
> The issignaling macro«:
> 
> | Synopsis
> | [1] #define __STDC_WANT_IEC_00000_EXT1__
> |     #include <math.h>
> |     int issignaling(real-floating x);
> | 
> | Description
> | [2] The issignaling macro determines whether its argument value is a signaling NaN, without
> |     raising a floating-point exception.
> | 
> | Returns
> | [3] The issignaling macro returns a nonzero value if and only if its argument is a signaling NaN.

I have now pushed a new version of this patch in the
tschwinge/issignaling branch.  Would machine maintainers please test this
branch/patch and report back?  Any new testsuite failures are
interesting, and especially also any differences in math/*.out files.

Carlos, is my understanding correct (based on a Wikipedia article), that
HPPA is (as MIPS) one of the few HIGH_ORDER_BIT_IS_SET_FOR_SNAN (see the
patch) architectures?

My own testing:

32-bit x86: OK.

x86_64: OK.

PowerPC -m64:

math/basic-test.out:
    Failure:  double x = (double) (long double) sNaN, !issignaling

That is, this type cast -- which is a IEEE 754-2008 general-computational
convertFormat operation (IEEE 754-2008, 5.4.2) -- does not turn the sNaN
into a qNaN (whilst raising an INVALID exception; not checked here),
which is contrary to IEEE 754-2008 5.1 and 7.2.  This I consider a
compiler issue (powerpc-linux-gnu-gcc (Sourcery CodeBench 2012.09-92)
4.7.2).

MIPS32 O32:

math/test-double.out, math/test-idouble.out:
    Result:
     is:         sNaN
     should be:  qNaN

Seen for qNaN inputs with: pow, remainder.

MIPS -mabi=64:

math/test-double.out, math/test-idouble.out: as MIPS32 O32.

math/test-ldouble.out, math/test-ildoubl.out:
    Result:
     is:         sNaN
     should be:  qNaN

Seen for different kinds of "invalid" input (out of range, +/-inf, NaN)
with: acos, asin, acosh, atanh, log, log10, log2, pow, sqrt, tgamma,
fmod, remainder.

MIPS -EL -msoft-float -mabi=64:

math/test-double.out, math/test-idouble.out: as MIPS32 O32.
math/test-ldouble.out, math/test-ildoubl.out: as MIPS -mabi=64.

The MIPS presumably are all consider bugs in the implementation due to
HIGH_ORDER_BIT_IS_SET_FOR_SNAN; to be worked on next.

diff --git NEWS NEWS
index f0965d6..0d70ead 100644
--- NEWS
+++ NEWS
@@ -26,6 +26,8 @@ Version 2.18
 
 * Added a benchmark framework to track performance of functions in glibc.
 
+* New <math.h> macro named issignaling to check for a signaling NaN (sNaN).
+  This is currently GNU-specific.
 \f
 Version 2.17
 
diff --git Versions.def Versions.def
index 7c7d1f8..0462239 100644
--- Versions.def
+++ Versions.def
@@ -58,6 +58,7 @@ libm {
   GLIBC_2.3.4
   GLIBC_2.4
   GLIBC_2.15
+  GLIBC_2.18
 }
 libnsl {
   GLIBC_2.0
diff --git include/math.h include/math.h
index 2b040c6..cbbce59 100644
--- include/math.h
+++ include/math.h
@@ -23,11 +23,14 @@ hidden_proto (__isnanl)
 
 libm_hidden_proto (__fpclassify)
 libm_hidden_proto (__fpclassifyf)
+libm_hidden_proto (__issignaling)
+libm_hidden_proto (__issignalingf)
 libm_hidden_proto (__exp)
 libm_hidden_proto (__expf)
 
 # ifndef __NO_LONG_DOUBLE_MATH
 libm_hidden_proto (__fpclassifyl)
+libm_hidden_proto (__issignalingl)
 libm_hidden_proto (__expl)
 libm_hidden_proto (__expm1l)
 # endif
diff --git manual/arith.texi manual/arith.texi
index faf25cc..0c0b53e 100644
--- manual/arith.texi
+++ manual/arith.texi
@@ -387,6 +387,13 @@ to
 @end smallexample
 @end deftypefn
 
+@comment math.h
+@comment GNU
+@deftypefn {Macro} int issignaling (@emph{float-type} @var{x})
+This macro returns a nonzero value if @var{x} is a signaling NaN
+(sNaN).  It is a GNU extension.
+@end deftypefn
+
 Another set of floating-point classification functions was provided by
 BSD.  @Theglibc{} also supports these functions; however, we
 recommend that you use the ISO C99 macros in new code.  Those are standard
diff --git manual/libm-err-tab.pl manual/libm-err-tab.pl
index 5aa2603..1564669 100755
--- manual/libm-err-tab.pl
+++ manual/libm-err-tab.pl
@@ -77,7 +77,9 @@ use vars qw (%results @all_floats %suffices @all_functions);
     "remainder", "remquo", "rint", "round", "scalb", "scalbn", "scalbln",
     "sin", "sincos", "sinh", "sqrt", "tan", "tanh", "tgamma",
     "trunc", "y0", "y1", "yn" );
-# "fpclassify", "isfinite", "isnormal", "signbit" are not tabulated
+# fpclassify, isnormal, isfinite, isinf, isnan, issignaling, signbit,
+# isgreater, isgreaterequal, isless, islessequal, islessgreater, isunordered
+# are not tabulated.
 
 if ($#ARGV == 0) {
   $sources = $ARGV[0];
diff --git math/Makefile math/Makefile
index e216dfb..f396ba2 100644
--- math/Makefile
+++ math/Makefile
@@ -58,7 +58,7 @@ libm-calls = e_acos e_acosh e_asin e_atan2 e_atanh e_cosh e_exp e_fmod	\
 	     s_catan s_casin s_ccos s_csin s_ctan s_ctanh s_cacos	\
 	     s_casinh s_cacosh s_catanh s_csqrt s_cpow s_cproj s_clog10 \
 	     s_fma s_lrint s_llrint s_lround s_llround e_exp10 w_log2	\
-	     s_isinf_ns $(calls:s_%=m_%) x2y2m1 k_casinh
+	     s_isinf_ns s_issignaling $(calls:s_%=m_%) x2y2m1 k_casinh
 
 include ../Makeconfig
 
diff --git math/Versions math/Versions
index 0988851..513ab14 100644
--- math/Versions
+++ math/Versions
@@ -198,4 +198,7 @@ libm {
     __gamma_r_finite; __gammaf_r_finite; __gammal_r_finite;
     __exp_finite; __expf_finite; __expl_finite;
   }
+  GLIBC_2.18 {
+    __issignaling; __issignalingf; __issignalingl;
+  }
 }
diff --git math/basic-test.c math/basic-test.c
index ffead2e..61df3a0 100644
--- math/basic-test.c
+++ math/basic-test.c
@@ -20,6 +20,9 @@
 #include <float.h>
 #include <stdio.h>
 
+#include <math-tests.h>
+
+
 static int errors = 0;
 
 
@@ -39,6 +42,10 @@ NAME (void)								      \
   /* Variables are declared volatile to forbid some compiler		      \
      optimizations.  */							      \
   volatile FLOAT Inf_var, qNaN_var, zero_var, one_var;			      \
+  /* A sNaN is only guaranteed to be representable in variables with */	      \
+  /* static (or thread-local) storage duration.  */			      \
+  static volatile FLOAT sNaN_var = __builtin_nans ## SUFFIX ("");	      \
+  static volatile FLOAT minus_sNaN_var = -__builtin_nans ## SUFFIX ("");      \
   FLOAT x1, x2;								      \
 									      \
   zero_var = 0.0;							      \
@@ -49,6 +56,8 @@ NAME (void)								      \
   (void) &zero_var;							      \
   (void) &one_var;							      \
   (void) &qNaN_var;							      \
+  (void) &sNaN_var;							      \
+  (void) &minus_sNaN_var;						      \
   (void) &Inf_var;							      \
 									      \
 									      \
@@ -56,16 +65,41 @@ NAME (void)								      \
   check (#FLOAT " isinf (-inf) == -1", isinf (-Inf_var) == -1);		      \
   check (#FLOAT " !isinf (1)", !(isinf (one_var)));			      \
   check (#FLOAT " !isinf (qNaN)", !(isinf (qNaN_var)));			      \
+  if (SNAN_TESTS (FLOAT))						      \
+    check (#FLOAT " !isinf (sNaN)", !(isinf (sNaN_var)));		      \
 									      \
   check (#FLOAT " isnan (qNaN)", isnan (qNaN_var));			      \
+  if (SNAN_TESTS (FLOAT))						      \
+    check (#FLOAT " isnan (sNaN)", isnan (sNaN_var));			      \
   check (#FLOAT " isnan (-qNaN)", isnan (-qNaN_var));			      \
+  if (SNAN_TESTS (FLOAT))						      \
+    check (#FLOAT " isnan (-sNaN)", isnan (minus_sNaN_var));		      \
   check (#FLOAT " !isnan (1)", !(isnan (one_var)));			      \
   check (#FLOAT " !isnan (inf)", !(isnan (Inf_var)));			      \
 									      \
+  check (#FLOAT " !issignaling (qNaN)", !(issignaling (qNaN_var)));	      \
+  if (SNAN_TESTS (FLOAT))						      \
+    check (#FLOAT " issignaling (sNaN)", issignaling (sNaN_var));	      \
+  check (#FLOAT " !issignaling (-qNaN)", !(issignaling (-qNaN_var)));	      \
+  if (SNAN_TESTS (FLOAT))						      \
+    check (#FLOAT " issignaling (-sNaN)", issignaling (minus_sNaN_var));      \
+  check (#FLOAT " !issignaling (1)", !(issignaling (one_var)));		      \
+  check (#FLOAT " !issignaling (inf)", !(issignaling (Inf_var)));	      \
+									      \
   check (#FLOAT " inf == inf", Inf_var == Inf_var);			      \
   check (#FLOAT " -inf == -inf", -Inf_var == -Inf_var);			      \
   check (#FLOAT " inf != -inf", Inf_var != -Inf_var);			      \
   check (#FLOAT " qNaN != qNaN", qNaN_var != qNaN_var);			      \
+  if (SNAN_TESTS (FLOAT))						      \
+    check (#FLOAT " sNaN != sNaN", sNaN_var != sNaN_var);		      \
+  if (SNAN_TESTS (FLOAT))						      \
+    check (#FLOAT " qNaN != sNaN", qNaN_var != sNaN_var);		      \
+  if (SNAN_TESTS (FLOAT))						      \
+    check (#FLOAT " -sNaN != -sNaN", minus_sNaN_var != minus_sNaN_var);	      \
+  if (SNAN_TESTS (FLOAT))						      \
+    check (#FLOAT " sNaN != -sNaN", sNaN_var != minus_sNaN_var);	      \
+  if (SNAN_TESTS (FLOAT))						      \
+    check (#FLOAT " qNaN != -sNaN", qNaN_var != minus_sNaN_var);	      \
 									      \
   /*									      \
      the same tests but this time with NAN from <bits/nan.h>		      \
@@ -76,6 +110,11 @@ NAME (void)								      \
   check (#FLOAT " !isinf (NAN)", !(isinf (NAN)));			      \
   check (#FLOAT " !isinf (-NAN)", !(isinf (-NAN)));			      \
   check (#FLOAT " NAN != NAN", NAN != NAN);				      \
+  check (#FLOAT " NAN != qNaN", NAN != qNaN_var);			      \
+  if (SNAN_TESTS (FLOAT))						      \
+    check (#FLOAT " NAN != sNaN", NAN != sNaN_var);			      \
+  if (SNAN_TESTS (FLOAT))						      \
+    check (#FLOAT " NAN != -sNaN", NAN != minus_sNaN_var);		      \
 									      \
   /*									      \
      And again with the value returned by the `nan' function.		      \
@@ -86,6 +125,12 @@ NAME (void)								      \
   check (#FLOAT " !isinf (-nan (\"\"))", !(isinf (-nan ## SUFFIX (""))));     \
   check (#FLOAT " nan (\"\") != nan (\"\")",				      \
 	 nan ## SUFFIX ("") != nan ## SUFFIX (""));			      \
+  check (#FLOAT " nan (\"\") != qNaN", nan ## SUFFIX ("") != qNaN_var);	      \
+  if (SNAN_TESTS (FLOAT))						      \
+    check (#FLOAT " nan (\"\") != sNaN", nan ## SUFFIX ("") != sNaN_var);     \
+  if (SNAN_TESTS (FLOAT))						      \
+    check (#FLOAT " nan (\"\") != -sNaN",				      \
+	   nan ## SUFFIX ("") != minus_sNaN_var);			      \
 									      \
   /* test if EPSILON is ok */						      \
   x1 = 1.0;								      \
@@ -108,6 +153,9 @@ void									      \
 NAME (void)								      \
 {									      \
   volatile DOUBLE Inf_var, qNaN_var, zero_var, one_var;			      \
+  /* A sNaN is only guaranteed to be representable in variables with */	      \
+  /* static (or thread-local) storage duration.  */			      \
+  static volatile DOUBLE sNaN_var = __builtin_nans ## SUFFIX ("");	      \
   FLOAT x1, x2;								      \
 									      \
   zero_var = 0.0;							      \
@@ -116,10 +164,22 @@ NAME (void)								      \
   Inf_var = one_var / zero_var;						      \
 									      \
   (void) &qNaN_var;							      \
+  (void) &sNaN_var;							      \
   (void) &Inf_var;							      \
 									      \
   x1 = (FLOAT) qNaN_var;						      \
-  check (" "#FLOAT" x = ("#FLOAT") ("#DOUBLE") qNaN", isnan (x1) != 0);	      \
+  check (" "#FLOAT" x = ("#FLOAT") ("#DOUBLE") qNaN, isnan", isnan (x1));     \
+  check (" "#FLOAT" x = ("#FLOAT") ("#DOUBLE") qNaN, !issignaling",	      \
+	 !issignaling (x1));						      \
+  if (SNAN_TESTS (FLOAT))						      \
+    {									      \
+      x1 = (FLOAT) sNaN_var;						      \
+      check (" "#FLOAT" x = ("#FLOAT") ("#DOUBLE") sNaN, isnan", isnan (x1)); \
+      /* Upon type conversion, a sNaN is converted into a qNaN plus an */     \
+      /* INVALID exception (not checked here).  */			      \
+      check (" "#FLOAT" x = ("#FLOAT") ("#DOUBLE") sNaN, !issignaling",	      \
+	     !issignaling (x1));					      \
+      }									      \
   x2 = (FLOAT) Inf_var;							      \
   check (" "#FLOAT" x = ("#FLOAT") ("#DOUBLE") Inf", isinf (x2) != 0);	      \
 }
diff --git math/bits/mathcalls.h math/bits/mathcalls.h
index e5af507..870c54c 100644
--- math/bits/mathcalls.h
+++ math/bits/mathcalls.h
@@ -360,6 +360,12 @@ __MATHCALL (fma,, (_Mdouble_ __x, _Mdouble_ __y, _Mdouble_ __z));
 __END_NAMESPACE_C99
 #endif
 
+#ifdef __USE_GNU
+/* Test for signaling NaN.  */
+__MATHDECL_1 (int, __issignaling,, (_Mdouble_ __value))
+     __attribute__ ((__const__));
+#endif
+
 #if defined __USE_MISC || defined __USE_XOPEN_EXTENDED
 /* Return X times (2 to the Nth power).  */
 __MATHCALL (scalb,, (_Mdouble_ __x, _Mdouble_ __n));
diff --git math/gen-libm-test.pl math/gen-libm-test.pl
index f50f1d9..aa60d9d 100755
--- math/gen-libm-test.pl
+++ math/gen-libm-test.pl
@@ -322,7 +322,7 @@ sub parse_args {
   }
   # Special handling for some macros:
   $cline .= " (\"$str\", ";
-  if ($args[0] =~ /fpclassify|isnormal|isfinite|isinf|isnan|signbit
+  if ($args[0] =~ /fpclassify|isnormal|isfinite|isinf|isnan|issignaling|signbit
       |isgreater|isgreaterequal|isless|islessequal
       |islessgreater|isunordered/x) {
     $c_call = "$args[0] (";
diff --git math/libm-test.inc math/libm-test.inc
index 1b70c35..d5bc060 100644
--- math/libm-test.inc
+++ math/libm-test.inc
@@ -42,7 +42,7 @@
    cbrt, ceil, copysign, cos, cosh, erf, erfc, exp, exp10, exp2, expm1,
    fabs, fdim, finite, floor, fma, fmax, fmin, fmod, fpclassify,
    frexp, gamma, hypot,
-   ilogb, isfinite, isinf, isnan, isnormal,
+   ilogb, isfinite, isinf, isnan, isnormal, issignaling,
    isless, islessequal, isgreater, isgreaterequal, islessgreater, isunordered,
    j0, j1, jn,
    ldexp, lgamma, log, log10, log1p, log2, logb,
@@ -87,9 +87,8 @@
    aren't checked at the moment.
 
    NaN values: There exist signalling and quiet NaNs.  This implementation
-   only uses quiet NaN as parameter but does not differentiate
-   between the two kinds of NaNs as result.  Where the sign of a NaN is
-   significant, this is not tested.
+   only uses quiet NaN as parameter.  Where the sign of a NaN is
+   significant, this is not tested.  The payload of NaNs is not examined.
 
    Inline functions: Inlining functions should give an improvement in
    speed - but not in precission.  The inlined functions return
@@ -263,6 +262,19 @@ set_max_error (FLOAT current, FLOAT *curr_max_error)
 }
 
 
+/* Print a FLOAT.  */
+static void
+print_float (FLOAT f)
+{
+  /* As printf doesn't differ between a sNaN and a qNaN, do this manually.  */
+  if (issignaling (f))
+    printf ("sNaN\n");
+  else if (isnan (f))
+    printf ("qNaN\n");
+  else
+    printf ("% .20" PRINTF_EXPR "  % .20" PRINTF_XEXPR "\n", f, f);
+}
+
 /* Should the message print to screen?  This depends on the verbose flag,
    and the test status.  */
 static int
@@ -532,7 +544,11 @@ check_float_internal (const char *test_name, FLOAT computed, FLOAT expected,
   FLOAT ulp = 0;
 
   test_exceptions (test_name, exceptions);
-  if (isnan (computed) && isnan (expected))
+  if (issignaling (computed) && issignaling (expected))
+    ok = 1;
+  else if (issignaling (computed) || issignaling (expected))
+    ok = 0;
+  else if (isnan (computed) && isnan (expected))
     ok = 1;
   else if (isinf (computed) && isinf (expected))
     {
@@ -546,8 +562,9 @@ check_float_internal (const char *test_name, FLOAT computed, FLOAT expected,
       else
 	ok = 1;
     }
-  /* Don't calc ulp for NaNs or infinities.  */
-  else if (isinf (computed) || isnan (computed) || isinf (expected) || isnan (expected))
+  /* Don't calculate ULPs for infinities or any kind of NaNs.  */
+  else if (isinf (computed) || isnan (computed)
+	   || isinf (expected) || isnan (expected))
     ok = 0;
   else
     {
@@ -592,10 +609,10 @@ check_float_internal (const char *test_name, FLOAT computed, FLOAT expected,
 	printf ("Failure: ");
       printf ("Test: %s\n", test_name);
       printf ("Result:\n");
-      printf (" is:         % .20" PRINTF_EXPR "  % .20" PRINTF_XEXPR "\n",
-	      computed, computed);
-      printf (" should be:  % .20" PRINTF_EXPR "  % .20" PRINTF_XEXPR "\n",
-	      expected, expected);
+      printf (" is:         ");
+      print_float (computed);
+      printf (" should be:  ");
+      print_float (expected);
       if (print_diff)
 	{
 	  printf (" difference: % .20" PRINTF_EXPR "  % .20" PRINTF_XEXPR
@@ -6440,6 +6457,22 @@ isnormal_test (void)
 }
 
 static void
+issignaling_test (void)
+{
+  START (issignaling);
+
+  TEST_f_b (issignaling, 0, 0);
+  TEST_f_b (issignaling, minus_zero, 0);
+  TEST_f_b (issignaling, 10, 0);
+  TEST_f_b (issignaling, min_subnorm_value, 0);
+  TEST_f_b (issignaling, plus_infty, 0);
+  TEST_f_b (issignaling, minus_infty, 0);
+  TEST_f_b (issignaling, qnan_value, 0);
+
+  END (issignaling);
+}
+
+static void
 isunordered_test (void)
 {
   START (isunordered);
@@ -11075,6 +11108,7 @@ main (int argc, char **argv)
   isinf_test ();
   isnan_test ();
   isnormal_test ();
+  issignaling_test ();
   signbit_test ();
 
   /* Trigonometric functions:  */
diff --git math/math.h math/math.h
index 2f25c23..e3adf09 100644
--- math/math.h
+++ math/math.h
@@ -282,6 +282,20 @@ enum
 
 #endif /* Use ISO C99.  */
 
+#ifdef __USE_GNU
+/* Return nonzero value if X is a signaling NaN.  */
+# ifdef __NO_LONG_DOUBLE_MATH
+#  define issignaling(x) \
+     (sizeof (x) == sizeof (float) ? __issignalingf (x) : __issignaling (x))
+# else
+#  define issignaling(x) \
+     (sizeof (x) == sizeof (float)					      \
+      ? __issignalingf (x)						      \
+      : sizeof (x) == sizeof (double)					      \
+      ? __issignaling (x) : __issignalingl (x))
+# endif
+#endif /* Use GNU.  */
+
 #ifdef	__USE_MISC
 /* Support for various different standard error handling behaviors.  */
 typedef enum
diff --git math/test-snan.c math/test-snan.c
index f185cbb..82f1dbe 100644
--- math/test-snan.c
+++ math/test-snan.c
@@ -1,4 +1,4 @@
-/* Test signaling NaNs in isnan, isinf, and similar functions.
+/* Test signaling NaNs in issignaling, isnan, isinf, and similar functions.
    Copyright (C) 2008-2013 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Andreas Jaeger <aj@suse.de>, 2005.
@@ -119,6 +119,48 @@ NAME (void)								      \
   feenableexcept (FE_ALL_EXCEPT);					      \
   if (sigsetjmp(sigfpe_buf, 0))						      \
     {									      \
+      printf (#FLOAT " issignaling (qNaN) raised SIGFPE\n");		      \
+      errors++;								      \
+    } else {								      \
+      check (#FLOAT " issignaling (qNaN)", !issignaling (qNaN_var));	      \
+    }									      \
+									      \
+  feclearexcept(FE_ALL_EXCEPT);						      \
+  feenableexcept (FE_ALL_EXCEPT);					      \
+  if (sigsetjmp(sigfpe_buf, 0))						      \
+    {									      \
+      printf (#FLOAT " issignaling (-qNaN) raised SIGFPE\n");		      \
+      errors++;								      \
+    } else {								      \
+      check (#FLOAT " issignaling (-qNaN)", !issignaling (-qNaN_var));	      \
+    }									      \
+									      \
+  feclearexcept(FE_ALL_EXCEPT);						      \
+  feenableexcept (FE_ALL_EXCEPT);					      \
+  if (sigsetjmp(sigfpe_buf, 0))						      \
+    {									      \
+      printf (#FLOAT " issignaling (sNaN) raised SIGFPE\n");		      \
+      errors++;								      \
+    } else {								      \
+      check (#FLOAT " issignaling (sNaN)",				      \
+	     SNAN_TESTS (FLOAT) ? issignaling (sNaN_var) : 1);		      \
+    }									      \
+									      \
+  feclearexcept(FE_ALL_EXCEPT);						      \
+  feenableexcept (FE_ALL_EXCEPT);					      \
+  if (sigsetjmp(sigfpe_buf, 0))						      \
+    {									      \
+      printf (#FLOAT " issignaling (-sNaN) raised SIGFPE\n");		      \
+      errors++;								      \
+    } else {								      \
+      check (#FLOAT " issignaling (-sNaN)",				      \
+	     SNAN_TESTS (FLOAT) ? issignaling (minus_sNaN_var) : 1);	      \
+    }									      \
+									      \
+  feclearexcept(FE_ALL_EXCEPT);						      \
+  feenableexcept (FE_ALL_EXCEPT);					      \
+  if (sigsetjmp(sigfpe_buf, 0))						      \
+    {									      \
       printf (#FLOAT " isnan (qNaN) raised SIGFPE\n");			      \
       errors++;								      \
     } else {								      \
diff --git ports/sysdeps/hppa/math_private.h ports/sysdeps/hppa/math_private.h
new file mode 100644
index 0000000..03b0711
--- /dev/null
+++ ports/sysdeps/hppa/math_private.h
@@ -0,0 +1,27 @@
+/* Internal math stuff.  HPPA version.
+   Copyright (C) 2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _MATH_PRIVATE_H
+
+/* One of the few architectures where the meaning of the quiet/signaling bit is
+   inverse to IEEE 754-2008 (as well as common practice for IEEE 754-1985).  */
+#define HIGH_ORDER_BIT_IS_SET_FOR_SNAN
+
+#include_next <math_private.h>
+
+#endif
diff --git ports/sysdeps/mips/math_private.h ports/sysdeps/mips/math_private.h
new file mode 100644
index 0000000..f0ba4ee
--- /dev/null
+++ ports/sysdeps/mips/math_private.h
@@ -0,0 +1,27 @@
+/* Internal math stuff.  MIPS version.
+   Copyright (C) 2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _MATH_PRIVATE_H
+
+/* One of the few architectures where the meaning of the quiet/signaling bit is
+   inverse to IEEE 754-2008 (as well as common practice for IEEE 754-1985).  */
+#define HIGH_ORDER_BIT_IS_SET_FOR_SNAN
+
+#include_next <math_private.h>
+
+#endif
diff --git ports/sysdeps/unix/sysv/linux/aarch64/nptl/libm.abilist ports/sysdeps/unix/sysv/linux/aarch64/nptl/libm.abilist
index 14b7edf..0f1cfc8 100644
--- ports/sysdeps/unix/sysv/linux/aarch64/nptl/libm.abilist
+++ ports/sysdeps/unix/sysv/linux/aarch64/nptl/libm.abilist
@@ -395,3 +395,8 @@ GLIBC_2.17
  yn F
  ynf F
  ynl F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __issignaling F
+ __issignalingf F
+ __issignalingl F
diff --git ports/sysdeps/unix/sysv/linux/alpha/nptl/libm.abilist ports/sysdeps/unix/sysv/linux/alpha/nptl/libm.abilist
index 9c4170d..400a851 100644
--- ports/sysdeps/unix/sysv/linux/alpha/nptl/libm.abilist
+++ ports/sysdeps/unix/sysv/linux/alpha/nptl/libm.abilist
@@ -391,6 +391,11 @@ GLIBC_2.15
  __yn_finite F
  __ynf_finite F
  __ynl_finite F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __issignaling F
+ __issignalingf F
+ __issignalingl F
 GLIBC_2.2
  GLIBC_2.2 A
  feclearexcept F
diff --git ports/sysdeps/unix/sysv/linux/arm/nptl/libm.abilist ports/sysdeps/unix/sysv/linux/arm/nptl/libm.abilist
index cee3472..614e5eb 100644
--- ports/sysdeps/unix/sysv/linux/arm/nptl/libm.abilist
+++ ports/sysdeps/unix/sysv/linux/arm/nptl/libm.abilist
@@ -54,6 +54,10 @@ GLIBC_2.15
  __y1f_finite F
  __yn_finite F
  __ynf_finite F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __issignaling F
+ __issignalingf F
 GLIBC_2.4
  GLIBC_2.4 A
  _LIB_VERSION D 0x4
diff --git ports/sysdeps/unix/sysv/linux/ia64/nptl/libm.abilist ports/sysdeps/unix/sysv/linux/ia64/nptl/libm.abilist
index 1fb51a1..db8b279 100644
--- ports/sysdeps/unix/sysv/linux/ia64/nptl/libm.abilist
+++ ports/sysdeps/unix/sysv/linux/ia64/nptl/libm.abilist
@@ -18,6 +18,11 @@ GLIBC_2.15
  __yn_finite F
  __ynf_finite F
  __ynl_finite F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __issignaling F
+ __issignalingf F
+ __issignalingl F
 GLIBC_2.2
  GLIBC_2.2 A
  _LIB_VERSION D 0x4
diff --git ports/sysdeps/unix/sysv/linux/m68k/coldfire/nptl/libm.abilist ports/sysdeps/unix/sysv/linux/m68k/coldfire/nptl/libm.abilist
index cee3472..614e5eb 100644
--- ports/sysdeps/unix/sysv/linux/m68k/coldfire/nptl/libm.abilist
+++ ports/sysdeps/unix/sysv/linux/m68k/coldfire/nptl/libm.abilist
@@ -54,6 +54,10 @@ GLIBC_2.15
  __y1f_finite F
  __yn_finite F
  __ynf_finite F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __issignaling F
+ __issignalingf F
 GLIBC_2.4
  GLIBC_2.4 A
  _LIB_VERSION D 0x4
diff --git ports/sysdeps/unix/sysv/linux/m68k/m680x0/nptl/libm.abilist ports/sysdeps/unix/sysv/linux/m68k/m680x0/nptl/libm.abilist
index 35fc1e3..0beecb7 100644
--- ports/sysdeps/unix/sysv/linux/m68k/m680x0/nptl/libm.abilist
+++ ports/sysdeps/unix/sysv/linux/m68k/m680x0/nptl/libm.abilist
@@ -396,6 +396,11 @@ GLIBC_2.15
  __yn_finite F
  __ynf_finite F
  __ynl_finite F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __issignaling F
+ __issignalingf F
+ __issignalingl F
 GLIBC_2.2
  GLIBC_2.2 A
  feclearexcept F
diff --git ports/sysdeps/unix/sysv/linux/mips/mips32/nptl/libm.abilist ports/sysdeps/unix/sysv/linux/mips/mips32/nptl/libm.abilist
index defa1b0..5381246 100644
--- ports/sysdeps/unix/sysv/linux/mips/mips32/nptl/libm.abilist
+++ ports/sysdeps/unix/sysv/linux/mips/mips32/nptl/libm.abilist
@@ -212,6 +212,10 @@ GLIBC_2.15
  __y1f_finite F
  __yn_finite F
  __ynf_finite F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __issignaling F
+ __issignalingf F
 GLIBC_2.2
  GLIBC_2.2 A
  __clog10 F
diff --git ports/sysdeps/unix/sysv/linux/mips/mips64/n32/nptl/libm.abilist ports/sysdeps/unix/sysv/linux/mips/mips64/n32/nptl/libm.abilist
index 064eeba..bb39795 100644
--- ports/sysdeps/unix/sysv/linux/mips/mips64/n32/nptl/libm.abilist
+++ ports/sysdeps/unix/sysv/linux/mips/mips64/n32/nptl/libm.abilist
@@ -239,6 +239,11 @@ GLIBC_2.15
  __yn_finite F
  __ynf_finite F
  __ynl_finite F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __issignaling F
+ __issignalingf F
+ __issignalingl F
 GLIBC_2.2
  GLIBC_2.2 A
  __clog10 F
diff --git ports/sysdeps/unix/sysv/linux/mips/mips64/n64/nptl/libm.abilist ports/sysdeps/unix/sysv/linux/mips/mips64/n64/nptl/libm.abilist
index 064eeba..bb39795 100644
--- ports/sysdeps/unix/sysv/linux/mips/mips64/n64/nptl/libm.abilist
+++ ports/sysdeps/unix/sysv/linux/mips/mips64/n64/nptl/libm.abilist
@@ -239,6 +239,11 @@ GLIBC_2.15
  __yn_finite F
  __ynf_finite F
  __ynl_finite F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __issignaling F
+ __issignalingf F
+ __issignalingl F
 GLIBC_2.2
  GLIBC_2.2 A
  __clog10 F
diff --git ports/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libm.abilist ports/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libm.abilist
index ddc8576..9bd593c 100644
--- ports/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libm.abilist
+++ ports/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libm.abilist
@@ -396,6 +396,11 @@ GLIBC_2.15
  __yn_finite F
  __ynf_finite F
  __ynl_finite F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __issignaling F
+ __issignalingf F
+ __issignalingl F
 GLIBC_2.2
  GLIBC_2.2 A
  feclearexcept F
diff --git ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/nptl/libm.abilist ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/nptl/libm.abilist
index 601b505..cb0d1a4 100644
--- ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/nptl/libm.abilist
+++ ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/nptl/libm.abilist
@@ -367,3 +367,7 @@ GLIBC_2.15
  __y1f_finite F
  __yn_finite F
  __ynf_finite F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __issignaling F
+ __issignalingf F
diff --git ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/nptl/libm.abilist ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/nptl/libm.abilist
index 601b505..cb0d1a4 100644
--- ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/nptl/libm.abilist
+++ ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/nptl/libm.abilist
@@ -367,3 +367,7 @@ GLIBC_2.15
  __y1f_finite F
  __yn_finite F
  __ynf_finite F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __issignaling F
+ __issignalingf F
diff --git ports/sysdeps/unix/sysv/linux/tile/tilepro/nptl/libm.abilist ports/sysdeps/unix/sysv/linux/tile/tilepro/nptl/libm.abilist
index 601b505..cb0d1a4 100644
--- ports/sysdeps/unix/sysv/linux/tile/tilepro/nptl/libm.abilist
+++ ports/sysdeps/unix/sysv/linux/tile/tilepro/nptl/libm.abilist
@@ -367,3 +367,7 @@ GLIBC_2.15
  __y1f_finite F
  __yn_finite F
  __ynf_finite F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __issignaling F
+ __issignalingf F
diff --git sysdeps/ieee754/dbl-64/s_issignaling.c sysdeps/ieee754/dbl-64/s_issignaling.c
new file mode 100644
index 0000000..caa761e
--- /dev/null
+++ sysdeps/ieee754/dbl-64/s_issignaling.c
@@ -0,0 +1,46 @@
+/* Test for signaling NaN.
+   Copyright (C) 2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+
+#undef __issignaling
+int __issignaling (double x)
+{
+#ifdef HIGH_ORDER_BIT_IS_SET_FOR_SNAN
+  u_int32_t hxi;
+  GET_HIGH_WORD (hxi, x);
+  /* We only have to care about the high-order bit of x's significand, because
+     having it set (sNaN) already makes the significand different from that
+     used to designate infinity.  */
+  return (hxi & 0x7ff80000) == 0x7ff80000;
+#else
+  u_int32_t hxi, lxi;
+  EXTRACT_WORDS (hxi, lxi, x);
+  /* To keep the following comparison simple, toggle the quiet/signaling bit,
+     so that it is set for sNaNs.  This is inverse to IEEE 754-2008 (as well as
+     common practice for IEEE 754-1985).  */
+  hxi ^= 0x00080000;
+  /* If lxi != 0, then set any suitable bit of the significand in hxi.  */
+  hxi |= (lxi | -lxi) >> 31;
+  /* We have to compare for greater (instead of greater or equal), because x's
+     significand being all-zero designates infinity not NaN.  */
+  return (hxi & 0x7fffffff) > 0x7ff80000;
+#endif
+}
+libm_hidden_def (__issignaling)
diff --git sysdeps/ieee754/dbl-64/wordsize-64/s_issignaling.c sysdeps/ieee754/dbl-64/wordsize-64/s_issignaling.c
new file mode 100644
index 0000000..5de76d4
--- /dev/null
+++ sysdeps/ieee754/dbl-64/wordsize-64/s_issignaling.c
@@ -0,0 +1,43 @@
+/* Test for signaling NaN.
+   Copyright (C) 2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+
+#undef __issignaling
+int __issignaling (double x)
+{
+  u_int64_t xi;
+  EXTRACT_WORDS64 (xi, x);
+#ifdef HIGH_ORDER_BIT_IS_SET_FOR_SNAN
+# error untested
+  /* We only have to care about the high-order bit of x's significand, because
+     having it set (sNaN) already makes the significand different from that
+     used to designate infinity.  */
+  return (xi & UINT64_C (0x7ff8000000000000)) == UINT64_C (0x7ff8000000000000);
+#else
+  /* To keep the following comparison simple, toggle the quiet/signaling bit,
+     so that it is set for sNaNs.  This is inverse to IEEE 754-2008 (as well as
+     common practice for IEEE 754-1985).  */
+  xi ^= UINT64_C (0x0008000000000000);
+  /* We have to compare for greater (instead of greater or equal), because x's
+     significand being all-zero designates infinity not NaN.  */
+  return (xi & UINT64_C (0x7fffffffffffffff)) > UINT64_C (0x7ff8000000000000);
+#endif
+}
+libm_hidden_def (__issignaling)
diff --git sysdeps/ieee754/flt-32/s_issignalingf.c sysdeps/ieee754/flt-32/s_issignalingf.c
new file mode 100644
index 0000000..2942002
--- /dev/null
+++ sysdeps/ieee754/flt-32/s_issignalingf.c
@@ -0,0 +1,42 @@
+/* Test for signaling NaN.
+   Copyright (C) 2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+
+#undef __issignalingf
+int __issignalingf (float x)
+{
+  u_int32_t xi;
+  GET_FLOAT_WORD (xi, x);
+#ifdef HIGH_ORDER_BIT_IS_SET_FOR_SNAN
+  /* We only have to care about the high-order bit of x's significand, because
+     having it set (sNaN) already makes the significand different from that
+     used to designate infinity.  */
+  return (xi & 0x7fc00000) == 0x7fc00000;
+#else
+  /* To keep the following comparison simple, toggle the quiet/signaling bit,
+     so that it is set for sNaNs.  This is inverse to IEEE 754-2008 (as well as
+     common practice for IEEE 754-1985).  */
+  xi ^= 0x00400000;
+  /* We have to compare for greater (instead of greater or equal), because x's
+     significand being all-zero designates infinity not NaN.  */
+  return (xi & 0x7fffffff) > 0x7fc00000;
+#endif
+}
+libm_hidden_def (__issignalingf)
diff --git sysdeps/ieee754/ldbl-128/s_issignalingl.c sysdeps/ieee754/ldbl-128/s_issignalingl.c
new file mode 100644
index 0000000..873074d
--- /dev/null
+++ sysdeps/ieee754/ldbl-128/s_issignalingl.c
@@ -0,0 +1,46 @@
+/* Test for signaling NaN.
+   Copyright (C) 2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+
+#undef __issignalingl
+int __issignalingl (long double x)
+{
+  u_int64_t hxi, lxi __attribute__ ((unused));
+  GET_LDOUBLE_WORDS64 (hxi, lxi, x);
+#ifdef HIGH_ORDER_BIT_IS_SET_FOR_SNAN
+  /* We only have to care about the high-order bit of x's significand, because
+     having it set (sNaN) already makes the significand different from that
+     used to designate infinity.  */
+  return ((hxi & UINT64_C (0x7fff800000000000))
+          == UINT64_C (0x7fff800000000000));
+#else
+# error untested
+  /* To keep the following comparison simple, toggle the quiet/signaling bit,
+     so that it is set for sNaNs.  This is inverse to IEEE 754-2008 (as well as
+     common practice for IEEE 754-1985).  */
+  hxi ^= UINT64_C (0x0000800000000000);
+  /* If lxi != 0, then set any suitable bit of the significand in hxi.  */
+  hxi |= (lxi | -lxi) >> 63;
+  /* We have to compare for greater (instead of greater or equal), because x's
+     significand being all-zero designates infinity not NaN.  */
+  return (hxi & UINT64_C (0x7fffffffffffffff)) > UINT64_C (0x7fff800000000000);
+#endif
+}
+libm_hidden_def (__issignalingl)
diff --git sysdeps/ieee754/ldbl-128ibm/s_issignalingl.c sysdeps/ieee754/ldbl-128ibm/s_issignalingl.c
new file mode 100644
index 0000000..daead8c
--- /dev/null
+++ sysdeps/ieee754/ldbl-128ibm/s_issignalingl.c
@@ -0,0 +1,45 @@
+/* Test for signaling NaN.
+   Copyright (C) 2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+
+#undef __issignalingl
+int __issignalingl (long double x)
+{
+  u_int64_t xi;
+  /* For inspecting NaN status, we only have to look at the first of the pair
+     of IEEE 754 64-bit precision numbers.  */
+  GET_LDOUBLE_MSW64 (xi, x);
+#ifdef HIGH_ORDER_BIT_IS_SET_FOR_SNAN
+# error untested
+  /* We only have to care about the high-order bit of x's significand, because
+     having it set (sNaN) already makes the significand different from that
+     used to designate infinity.  */
+  return (xi & UINT64_C (0x7ff8000000000000)) == UINT64_C (0x7ff8000000000000);
+#else
+  /* To keep the following comparison simple, toggle the quiet/signaling bit,
+     so that it is set for sNaNs.  This is inverse to IEEE 754-2008 (as well as
+     common practice for IEEE 754-1985).  */
+  xi ^= UINT64_C (0x0008000000000000);
+  /* We have to compare for greater (instead of greater or equal), because x's
+     significand being all-zero designates infinity not NaN.  */
+  return (xi & UINT64_C (0x7fffffffffffffff)) > UINT64_C (0x7ff8000000000000);
+#endif
+}
+libm_hidden_def (__issignalingl)
diff --git sysdeps/ieee754/ldbl-96/s_issignalingl.c sysdeps/ieee754/ldbl-96/s_issignalingl.c
new file mode 100644
index 0000000..614e253
--- /dev/null
+++ sysdeps/ieee754/ldbl-96/s_issignalingl.c
@@ -0,0 +1,43 @@
+/* Test for signaling NaN.
+   Copyright (C) 2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+
+#undef __issignalingl
+int __issignalingl (long double x)
+{
+  u_int32_t exi, hxi, lxi;
+  GET_LDOUBLE_WORDS (exi, hxi, lxi, x);
+#ifdef HIGH_ORDER_BIT_IS_SET_FOR_SNAN
+# error not implemented
+#else
+  /* To keep the following comparison simple, toggle the quiet/signaling bit,
+     so that it is set for sNaNs.  This is inverse to IEEE 754-2008 (as well as
+     common practice for IEEE 754-1985).  */
+  hxi ^= 0x40000000;
+  /* If lxi != 0, then set any suitable bit of the significand in hxi.  */
+  hxi |= (lxi | -lxi) >> 31;
+  /* We do not recognize a pseudo NaN as sNaN; they're invalid on 80387 and
+     later.  */
+  /* We have to compare for greater (instead of greater or equal), because x's
+     significand being all-zero designates infinity not NaN.  */
+  return ((exi & 0x7fff) == 0x7fff) && (hxi > 0xc0000000);
+#endif
+}
+libm_hidden_def (__issignalingl)
diff --git sysdeps/unix/sysv/linux/i386/nptl/libm.abilist sysdeps/unix/sysv/linux/i386/nptl/libm.abilist
index 401a2c6..c185f0b 100644
--- sysdeps/unix/sysv/linux/i386/nptl/libm.abilist
+++ sysdeps/unix/sysv/linux/i386/nptl/libm.abilist
@@ -396,6 +396,11 @@ GLIBC_2.15
  __yn_finite F
  __ynf_finite F
  __ynl_finite F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __issignaling F
+ __issignalingf F
+ __issignalingl F
 GLIBC_2.2
  GLIBC_2.2 A
  __expl F
diff --git sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libm.abilist sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libm.abilist
index 620aff9..76a4ba3 100644
--- sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libm.abilist
+++ sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libm.abilist
@@ -397,6 +397,11 @@ GLIBC_2.15
  __yn_finite F
  __ynf_finite F
  __ynl_finite F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __issignaling F
+ __issignalingf F
+ __issignalingl F
 GLIBC_2.2
  GLIBC_2.2 A
  feclearexcept F
diff --git sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libm.abilist sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libm.abilist
index 89422ab..d309a6f 100644
--- sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libm.abilist
+++ sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libm.abilist
@@ -81,6 +81,11 @@ GLIBC_2.15
  __yn_finite F
  __ynf_finite F
  __ynl_finite F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __issignaling F
+ __issignalingf F
+ __issignalingl F
 GLIBC_2.3
  GLIBC_2.3 A
  _LIB_VERSION D 0x4
diff --git sysdeps/unix/sysv/linux/s390/s390-32/nptl/libm.abilist sysdeps/unix/sysv/linux/s390/s390-32/nptl/libm.abilist
index ae8af50..f836c90 100644
--- sysdeps/unix/sysv/linux/s390/s390-32/nptl/libm.abilist
+++ sysdeps/unix/sysv/linux/s390/s390-32/nptl/libm.abilist
@@ -393,6 +393,11 @@ GLIBC_2.15
  __yn_finite F
  __ynf_finite F
  __ynl_finite F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __issignaling F
+ __issignalingf F
+ __issignalingl F
 GLIBC_2.2
  GLIBC_2.2 A
  fedisableexcept F
diff --git sysdeps/unix/sysv/linux/s390/s390-64/nptl/libm.abilist sysdeps/unix/sysv/linux/s390/s390-64/nptl/libm.abilist
index acf4d68..a0891ad 100644
--- sysdeps/unix/sysv/linux/s390/s390-64/nptl/libm.abilist
+++ sysdeps/unix/sysv/linux/s390/s390-64/nptl/libm.abilist
@@ -81,6 +81,11 @@ GLIBC_2.15
  __yn_finite F
  __ynf_finite F
  __ynl_finite F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __issignaling F
+ __issignalingf F
+ __issignalingl F
 GLIBC_2.2
  GLIBC_2.2 A
  _LIB_VERSION D 0x4
diff --git sysdeps/unix/sysv/linux/sh/nptl/libm.abilist sysdeps/unix/sysv/linux/sh/nptl/libm.abilist
index d851929..92821fd 100644
--- sysdeps/unix/sysv/linux/sh/nptl/libm.abilist
+++ sysdeps/unix/sysv/linux/sh/nptl/libm.abilist
@@ -54,6 +54,10 @@ GLIBC_2.15
  __y1f_finite F
  __yn_finite F
  __ynf_finite F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __issignaling F
+ __issignalingf F
 GLIBC_2.2
  GLIBC_2.2 A
  _LIB_VERSION D 0x4
diff --git sysdeps/unix/sysv/linux/sparc/sparc32/nptl/libm.abilist sysdeps/unix/sysv/linux/sparc/sparc32/nptl/libm.abilist
index 4c6ec6b..9a1fcb1 100644
--- sysdeps/unix/sysv/linux/sparc/sparc32/nptl/libm.abilist
+++ sysdeps/unix/sysv/linux/sparc/sparc32/nptl/libm.abilist
@@ -388,6 +388,11 @@ GLIBC_2.15
  __yn_finite F
  __ynf_finite F
  __ynl_finite F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __issignaling F
+ __issignalingf F
+ __issignalingl F
 GLIBC_2.2
  GLIBC_2.2 A
  feclearexcept F
diff --git sysdeps/unix/sysv/linux/sparc/sparc64/nptl/libm.abilist sysdeps/unix/sysv/linux/sparc/sparc64/nptl/libm.abilist
index 22fb92a..2b41d34 100644
--- sysdeps/unix/sysv/linux/sparc/sparc64/nptl/libm.abilist
+++ sysdeps/unix/sysv/linux/sparc/sparc64/nptl/libm.abilist
@@ -81,6 +81,11 @@ GLIBC_2.15
  __yn_finite F
  __ynf_finite F
  __ynl_finite F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __issignaling F
+ __issignalingf F
+ __issignalingl F
 GLIBC_2.2
  GLIBC_2.2 A
  _LIB_VERSION D 0x4
diff --git sysdeps/unix/sysv/linux/x86_64/64/nptl/libm.abilist sysdeps/unix/sysv/linux/x86_64/64/nptl/libm.abilist
index 7bf568c..2390934 100644
--- sysdeps/unix/sysv/linux/x86_64/64/nptl/libm.abilist
+++ sysdeps/unix/sysv/linux/x86_64/64/nptl/libm.abilist
@@ -81,6 +81,11 @@ GLIBC_2.15
  __yn_finite F
  __ynf_finite F
  __ynl_finite F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __issignaling F
+ __issignalingf F
+ __issignalingl F
 GLIBC_2.2.5
  GLIBC_2.2.5 A
  _LIB_VERSION D 0x4
diff --git sysdeps/unix/sysv/linux/x86_64/x32/nptl/libm.abilist sysdeps/unix/sysv/linux/x86_64/x32/nptl/libm.abilist
index 0f3ea4b..1825adb 100644
--- sysdeps/unix/sysv/linux/x86_64/x32/nptl/libm.abilist
+++ sysdeps/unix/sysv/linux/x86_64/x32/nptl/libm.abilist
@@ -395,3 +395,8 @@ GLIBC_2.16
  yn F
  ynf F
  ynl F
+GLIBC_2.18
+ GLIBC_2.18 A
+ __issignaling F
+ __issignalingf F
+ __issignalingl F


Grüße,
 Thomas

[-- Attachment #2: Type: application/pgp-signature, Size: 489 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [attention machine maintainers] [PATCH] <math.h> issignaling
  2013-03-22 11:18 ` [attention machine maintainers] [PATCH] <math.h> issignaling Thomas Schwinge
@ 2013-03-24 21:30   ` David Miller
  2013-03-25  6:52     ` Thomas Schwinge
  2013-03-25 15:54   ` Carlos O'Donell
  2013-03-26 17:34   ` Joseph S. Myers
  2 siblings, 1 reply; 8+ messages in thread
From: David Miller @ 2013-03-24 21:30 UTC (permalink / raw)
  To: thomas; +Cc: libc-alpha, libc-ports

From: Thomas Schwinge <thomas@codesourcery.com>
Date: Fri, 22 Mar 2013 12:17:19 +0100

> I have now pushed a new version of this patch in the
> tschwinge/issignaling branch.  Would machine maintainers please test
> this branch/patch and report back?

It doesn't even build on sparc because the code block that is
CPP enabled in the ldbl-128 version of issignaling() has
an #error in it.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [attention machine maintainers] [PATCH] <math.h> issignaling
  2013-03-24 21:30   ` David Miller
@ 2013-03-25  6:52     ` Thomas Schwinge
  2013-03-25 18:39       ` David Miller
  0 siblings, 1 reply; 8+ messages in thread
From: Thomas Schwinge @ 2013-03-25  6:52 UTC (permalink / raw)
  To: David Miller; +Cc: libc-alpha, libc-ports

[-- Attachment #1: Type: text/plain, Size: 717 bytes --]

Hi!

On Sun, 24 Mar 2013 17:30:33 -0400, David Miller <davem@davemloft.net> wrote:
> From: Thomas Schwinge <thomas@codesourcery.com>
> Date: Fri, 22 Mar 2013 12:17:19 +0100
> 
> > I have now pushed a new version of this patch in the
> > tschwinge/issignaling branch.  Would machine maintainers please test
> > this branch/patch and report back?
> 
> It doesn't even build on sparc because the code block that is
> CPP enabled in the ldbl-128 version of issignaling() has
> an #error in it.

Yes, because that code has not yet been tested, as the #error says --
sorry for not telling that in advance.  Do you want me to publish a new
branch and/or patch with that line removed?


Grüße,
 Thomas

[-- Attachment #2: Type: application/pgp-signature, Size: 489 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [attention machine maintainers] [PATCH] <math.h> issignaling
  2013-03-22 11:18 ` [attention machine maintainers] [PATCH] <math.h> issignaling Thomas Schwinge
  2013-03-24 21:30   ` David Miller
@ 2013-03-25 15:54   ` Carlos O'Donell
  2013-03-26 17:34   ` Joseph S. Myers
  2 siblings, 0 replies; 8+ messages in thread
From: Carlos O'Donell @ 2013-03-25 15:54 UTC (permalink / raw)
  To: Thomas Schwinge; +Cc: libc-alpha, libc-ports

On 03/22/2013 07:17 AM, Thomas Schwinge wrote:
> Hi!
> 
> On Wed, 06 Mar 2013 18:56:28 +0100, I wrote:
>> In IEEE 754-1985, »Annex A Recommended Functions and Predicates«, 10) a
>> function to distinguish signaling from quiet NaNs is suggested.  This is
>> further elaborated in IEEE 754-2008, »5.7.2 General operations« as a
>> isSignaling operation.  Such a macro/function is not yet part of any
>> published revision of the C programming language standard, but has been
>> under discussion for some time alreay, see for example in
>> <http://www.open-std.org/jtc1/sc22/wg14/www/docs/PostPortland2012.htm>'s
>> N1664 (the latest of its kind that is publically available, as far as I
>> know), »14.7 Inquiry macros [...] Suggested change to C11: [...] 7.12.3.7
>> The issignaling macro«:
>>
>> | Synopsis
>> | [1] #define __STDC_WANT_IEC_00000_EXT1__
>> |     #include <math.h>
>> |     int issignaling(real-floating x);
>> | 
>> | Description
>> | [2] The issignaling macro determines whether its argument value is a signaling NaN, without
>> |     raising a floating-point exception.
>> | 
>> | Returns
>> | [3] The issignaling macro returns a nonzero value if and only if its argument is a signaling NaN.
> 
> I have now pushed a new version of this patch in the
> tschwinge/issignaling branch.  Would machine maintainers please test this
> branch/patch and report back?  Any new testsuite failures are
> interesting, and especially also any differences in math/*.out files.
> 
> Carlos, is my understanding correct (based on a Wikipedia article), that
> HPPA is (as MIPS) one of the few HIGH_ORDER_BIT_IS_SET_FOR_SNAN (see the
> patch) architectures?

Correct.

I have verified this for you here:
~~~
PA-RISC 2.0 Architecture:
Floating-point Coprocessor 8-7
"If the number is a NaN, then the leftmost bit in the fraction, b1,
determines whether the NaN is signaling or quiet. If b1 is 1, the
NaN is a signaling NaN. If b1 is 0, it is a quiet NaN."
~~~

> --- /dev/null
> +++ ports/sysdeps/hppa/math_private.h
> @@ -0,0 +1,27 @@
> +/* Internal math stuff.  HPPA version.
> +   Copyright (C) 2013 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef _MATH_PRIVATE_H
> +
> +/* One of the few architectures where the meaning of the quiet/signaling bit is
> +   inverse to IEEE 754-2008 (as well as common practice for IEEE 754-1985).  */
> +#define HIGH_ORDER_BIT_IS_SET_FOR_SNAN
> +
> +#include_next <math_private.h>
> +
> +#endif

This looks good to me.

Cheers,
Carlos.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [attention machine maintainers] [PATCH] <math.h> issignaling
  2013-03-25  6:52     ` Thomas Schwinge
@ 2013-03-25 18:39       ` David Miller
  0 siblings, 0 replies; 8+ messages in thread
From: David Miller @ 2013-03-25 18:39 UTC (permalink / raw)
  To: thomas; +Cc: libc-alpha, libc-ports

From: Thomas Schwinge <thomas@codesourcery.com>
Date: Mon, 25 Mar 2013 07:52:31 +0100

> On Sun, 24 Mar 2013 17:30:33 -0400, David Miller <davem@davemloft.net> wrote:
>> From: Thomas Schwinge <thomas@codesourcery.com>
>> Date: Fri, 22 Mar 2013 12:17:19 +0100
>> 
>> > I have now pushed a new version of this patch in the
>> > tschwinge/issignaling branch.  Would machine maintainers please test
>> > this branch/patch and report back?
>> 
>> It doesn't even build on sparc because the code block that is
>> CPP enabled in the ldbl-128 version of issignaling() has
>> an #error in it.
> 
> Yes, because that code has not yet been tested, as the #error says --
> sorry for not telling that in advance.  Do you want me to publish a new
> branch and/or patch with that line removed?

With the #error line removed, sparc builds cleanly and there are no
testsuite regressions.

I tested with 32-bit sparc V9, which is generally very harmonious with
64-bit sparc.  But I'll kick off a 64-bit build as well and let you
know if anything turns up.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [attention machine maintainers] [PATCH] <math.h> issignaling
  2013-03-22 11:18 ` [attention machine maintainers] [PATCH] <math.h> issignaling Thomas Schwinge
  2013-03-24 21:30   ` David Miller
  2013-03-25 15:54   ` Carlos O'Donell
@ 2013-03-26 17:34   ` Joseph S. Myers
  2013-03-28 12:16     ` Thomas Schwinge
  2 siblings, 1 reply; 8+ messages in thread
From: Joseph S. Myers @ 2013-03-26 17:34 UTC (permalink / raw)
  To: Thomas Schwinge; +Cc: libc-alpha, libc-ports

On Fri, 22 Mar 2013, Thomas Schwinge wrote:

> PowerPC -m64:
> 
> math/basic-test.out:
>     Failure:  double x = (double) (long double) sNaN, !issignaling
> 
> That is, this type cast -- which is a IEEE 754-2008 general-computational
> convertFormat operation (IEEE 754-2008, 5.4.2) -- does not turn the sNaN
> into a qNaN (whilst raising an INVALID exception; not checked here),
> which is contrary to IEEE 754-2008 5.1 and 7.2.  This I consider a
> compiler issue (powerpc-linux-gnu-gcc (Sourcery CodeBench 2012.09-92)
> 4.7.2).

Such a bug (assuming present in GCC trunk for 4.9) should be filed in GCC 
Bugzilla (and I suppose a new math-tests.h macro used to disable the test 
in question for older compilers).  Though I guess it might only be desired 
to change this for -fsignaling-nans.

> MIPS32 O32:
> 
> math/test-double.out, math/test-idouble.out:
>     Result:
>      is:         sNaN
>      should be:  qNaN
> 
> Seen for qNaN inputs with: pow, remainder.

The issue for remainder comes from the use of NaN representations in 
sysdeps/ieee754/dbl-64/e_remainder.c.  In all such cases, for NaN input an 
output NaN should be generated by arithmetic involving the inputs, and for 
non-NaN input an output NaN should be generated by an arithmetic operation 
that generates a NaN and raises INVALID (without other exceptions).  The 
cases of missing INVALID for this (which only appear with -lieee, so need 
testsuite enhancements to test that case in order to be able to test fixes 
for them) are bug 14686.

As usual, file bugs with testcases in glibc Bugzilla for the MIPS-specific 
problems before fixing them.

> diff --git NEWS NEWS
> index f0965d6..0d70ead 100644
> --- NEWS
> +++ NEWS
> @@ -26,6 +26,8 @@ Version 2.18
>  
>  * Added a benchmark framework to track performance of functions in glibc.
>  
> +* New <math.h> macro named issignaling to check for a signaling NaN (sNaN).
> +  This is currently GNU-specific.

"GNU-specific" is a bit misleading there.  I think you mean "only defined 
if _GNU_SOURCE is defined" (but you should note it comes from draft TS 
18661).

> +@comment math.h
> +@comment GNU
> +@deftypefn {Macro} int issignaling (@emph{float-type} @var{x})
> +This macro returns a nonzero value if @var{x} is a signaling NaN
> +(sNaN).  It is a GNU extension.

A GNU extension based on draft TS 18661.

> +#undef __issignaling

Why the #undef?

> +int __issignaling (double x)

Return type on a separate line.

Same comments apply to the other implementations.

> +{
> +#ifdef HIGH_ORDER_BIT_IS_SET_FOR_SNAN
> +  u_int32_t hxi;

(I tend to think that the C99 names such as uint32_t should be preferred, 
but since the libm code seems to be using the legacy names universally, 
any such change should probably first be made globally to existing code if 
there's consensus, rather than making this code in particular different.)

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [attention machine maintainers] [PATCH] <math.h> issignaling
  2013-03-26 17:34   ` Joseph S. Myers
@ 2013-03-28 12:16     ` Thomas Schwinge
  2013-04-03 12:17       ` Thomas Schwinge
  0 siblings, 1 reply; 8+ messages in thread
From: Thomas Schwinge @ 2013-03-28 12:16 UTC (permalink / raw)
  To: libc-alpha, libc-ports; +Cc: joseph, azanella, davem

[-- Attachment #1: Type: text/plain, Size: 8914 bytes --]

Hi!

I plan to shortly "move" this patch (as present in the
tschwinge/issignaling branch) into master with the following changes
merged in, unless there are any further comments at this point.


On Tue, 26 Mar 2013 17:33:46 +0000, "Joseph S. Myers" <joseph@codesourcery.com> wrote:
> On Fri, 22 Mar 2013, Thomas Schwinge wrote:
> 
> > PowerPC -m64:
> > 
> > math/basic-test.out:
> >     Failure:  double x = (double) (long double) sNaN, !issignaling
> > 
> > That is, this type cast -- which is a IEEE 754-2008 general-computational
> > convertFormat operation (IEEE 754-2008, 5.4.2) -- does not turn the sNaN
> > into a qNaN (whilst raising an INVALID exception; not checked here),
> > which is contrary to IEEE 754-2008 5.1 and 7.2.  This I consider a
> > compiler issue (powerpc-linux-gnu-gcc (Sourcery CodeBench 2012.09-92)
> > 4.7.2).
> 
> Such a bug (assuming present in GCC trunk for 4.9) should be filed in GCC 
> Bugzilla (and I suppose a new math-tests.h macro used to disable the test 
> in question for older compilers).  Though I guess it might only be desired 
> to change this for -fsignaling-nans.

I will add the following, file in GCC Bugzilla, add its PR number to the
math_tests.h comment (also for the 32-bit x86 issue discussed before):

--- math/basic-test.c
+++ math/basic-test.c
@@ -175,10 +175,13 @@ NAME (void)								      \
     {									      \
       x1 = (FLOAT) sNaN_var;						      \
       check (" "#FLOAT" x = ("#FLOAT") ("#DOUBLE") sNaN, isnan", isnan (x1)); \
-      /* Upon type conversion, a sNaN is converted into a qNaN plus an */     \
-      /* INVALID exception (not checked here).  */			      \
-      check (" "#FLOAT" x = ("#FLOAT") ("#DOUBLE") sNaN, !issignaling",	      \
-	     !issignaling (x1));					      \
+      if (SNAN_TESTS_TYPE_CAST)						      \
+	{								      \
+	  /* Upon type conversion, a sNaN is converted into a qNaN plus an */ \
+	  /* INVALID exception (not checked here).  */			      \
+	  check (" "#FLOAT" x = ("#FLOAT") ("#DOUBLE") sNaN, !issignaling",   \
+		 !issignaling (x1));					      \
+	}								      \
       }									      \
   x2 = (FLOAT) Inf_var;							      \
   check (" "#FLOAT" x = ("#FLOAT") ("#DOUBLE") Inf", isinf (x2) != 0);	      \
--- sysdeps/generic/math-tests.h
+++ sysdeps/generic/math-tests.h
@@ -34,3 +34,9 @@
   (sizeof (x) == sizeof (float) ? SNAN_TESTS_float			\
    : sizeof (x) == sizeof (double) ? SNAN_TESTS_double			\
    : SNAN_TESTS_long_double)
+
+/* Indicate whether to run tests involving type casts of sNaN values.  These
+   are run unless overridden.  */
+#ifndef SNAN_TESTS_TYPE_CAST
+# define SNAN_TESTS_TYPE_CAST	1
+#endif
--- /dev/null
+++ sysdeps/powerpc/math-tests.h
@@ -0,0 +1,26 @@
+/* Configuration for math tests.  PowerPC version.
+   Copyright (C) 2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* On PowerPC, in versions of GCC up to at least 4.7.2, a type cast -- which is
+   a IEEE 754-2008 general-computational convertFormat operation (IEEE
+   754-2008, 5.4.2) -- does not turn a sNaN into a qNaN (whilst raising an
+   INVALID exception), which is contrary to IEEE 754-2008 5.1 and 7.2.  This
+   renders certain tests infeasible in this scenario.  */
+#define SNAN_TESTS_TYPE_CAST	0
+
+#include_next <math-tests.h>


> > --- NEWS
> > +++ NEWS
> > @@ -26,6 +26,8 @@ Version 2.18
> >  
> >  * Added a benchmark framework to track performance of functions in glibc.
> >  
> > +* New <math.h> macro named issignaling to check for a signaling NaN (sNaN).
> > +  This is currently GNU-specific.
> 
> "GNU-specific" is a bit misleading there.  I think you mean "only defined 
> if _GNU_SOURCE is defined" (but you should note it comes from draft TS 
> 18661).
> 
> > +@comment math.h
> > +@comment GNU
> > +@deftypefn {Macro} int issignaling (@emph{float-type} @var{x})
> > +This macro returns a nonzero value if @var{x} is a signaling NaN
> > +(sNaN).  It is a GNU extension.
> 
> A GNU extension based on draft TS 18661.

I plan to change the wording as follows in both cases:

--- NEWS
+++ NEWS
@@ -27,7 +27,7 @@ Version 2.18
 * Added a benchmark framework to track performance of functions in glibc.
 
 * New <math.h> macro named issignaling to check for a signaling NaN (sNaN).
-  This is currently GNU-specific.
+  It is based on draft TS 18661 and currently enabled as a GNU extension.
 \f
 Version 2.17
 
--- manual/arith.texi
+++ manual/arith.texi
@@ -391,7 +391,8 @@ to
 @comment GNU
 @deftypefn {Macro} int issignaling (@emph{float-type} @var{x})
 This macro returns a nonzero value if @var{x} is a signaling NaN
-(sNaN).  It is a GNU extension.
+(sNaN).  It is based on draft TS 18661 and currently enabled as a GNU
+extension.
 @end deftypefn
 
 Another set of floating-point classification functions was provided by


> > +#undef __issignaling
> 
> Why the #undef?

In case a machine-specific header file is defining a macro of the same
name; though you're correct that is not needed at this point.  Removed.

> > +int __issignaling (double x)
> 
> Return type on a separate line.

Changed.

--- sysdeps/ieee754/dbl-64/s_issignaling.c
+++ sysdeps/ieee754/dbl-64/s_issignaling.c
@@ -19,8 +19,8 @@
 #include <math.h>
 #include <math_private.h>
 
-#undef __issignaling
-int __issignaling (double x)
+int
+__issignaling (double x)
 {
 #ifdef HIGH_ORDER_BIT_IS_SET_FOR_SNAN
   u_int32_t hxi;
--- sysdeps/ieee754/dbl-64/wordsize-64/s_issignaling.c
+++ sysdeps/ieee754/dbl-64/wordsize-64/s_issignaling.c
@@ -19,8 +19,8 @@
 #include <math.h>
 #include <math_private.h>
 
-#undef __issignaling
-int __issignaling (double x)
+int
+__issignaling (double x)
 {
   u_int64_t xi;
   EXTRACT_WORDS64 (xi, x);
--- sysdeps/ieee754/flt-32/s_issignalingf.c
+++ sysdeps/ieee754/flt-32/s_issignalingf.c
@@ -19,8 +19,8 @@
 #include <math.h>
 #include <math_private.h>
 
-#undef __issignalingf
-int __issignalingf (float x)
+int
+__issignalingf (float x)
 {
   u_int32_t xi;
   GET_FLOAT_WORD (xi, x);
--- sysdeps/ieee754/ldbl-128/s_issignalingl.c
+++ sysdeps/ieee754/ldbl-128/s_issignalingl.c
@@ -19,8 +19,8 @@
 #include <math.h>
 #include <math_private.h>
 
-#undef __issignalingl
-int __issignalingl (long double x)
+int
+__issignalingl (long double x)
 {
   u_int64_t hxi, lxi __attribute__ ((unused));
   GET_LDOUBLE_WORDS64 (hxi, lxi, x);
--- sysdeps/ieee754/ldbl-128ibm/s_issignalingl.c
+++ sysdeps/ieee754/ldbl-128ibm/s_issignalingl.c
@@ -19,8 +19,8 @@
 #include <math.h>
 #include <math_private.h>
 
-#undef __issignalingl
-int __issignalingl (long double x)
+int
+__issignalingl (long double x)
 {
   u_int64_t xi;
   /* For inspecting NaN status, we only have to look at the first of the pair
--- sysdeps/ieee754/ldbl-96/s_issignalingl.c
+++ sysdeps/ieee754/ldbl-96/s_issignalingl.c
@@ -19,8 +19,8 @@
 #include <math.h>
 #include <math_private.h>
 
-#undef __issignalingl
-int __issignalingl (long double x)
+int
+__issignalingl (long double x)
 {
   u_int32_t exi, hxi, lxi;
   GET_LDOUBLE_WORDS (exi, hxi, lxi, x);


I also removed one »#error untested« after Dave's testing:

--- sysdeps/ieee754/ldbl-128/s_issignalingl.c
+++ sysdeps/ieee754/ldbl-128/s_issignalingl.c
@@ -31,7 +31,6 @@ int __issignalingl (long double x)
   return ((hxi & UINT64_C (0x7fff800000000000))
           == UINT64_C (0x7fff800000000000));
 #else
-# error untested
   /* To keep the following comparison simple, toggle the quiet/signaling bit,
      so that it is set for sNaNs.  This is inverse to IEEE 754-2008 (as well as
      common practice for IEEE 754-1985).  */


> > +{
> > +#ifdef HIGH_ORDER_BIT_IS_SET_FOR_SNAN
> > +  u_int32_t hxi;
> 
> (I tend to think that the C99 names such as uint32_t should be preferred, 
> but since the libm code seems to be using the legacy names universally, 
> any such change should probably first be made globally to existing code if 
> there's consensus, rather than making this code in particular different.)

Exactly my thoughts.


Grüße,
 Thomas

[-- Attachment #2: Type: application/pgp-signature, Size: 489 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [attention machine maintainers] [PATCH] <math.h> issignaling
  2013-03-28 12:16     ` Thomas Schwinge
@ 2013-04-03 12:17       ` Thomas Schwinge
  0 siblings, 0 replies; 8+ messages in thread
From: Thomas Schwinge @ 2013-04-03 12:17 UTC (permalink / raw)
  To: libc-alpha, libc-ports; +Cc: joseph, azanella, davem

[-- Attachment #1: Type: text/plain, Size: 3024 bytes --]

Hi!

On Thu, 28 Mar 2013 13:16:31 +0100, I wrote:
> I plan to shortly "move" this patch (as present in the
> tschwinge/issignaling branch) into master with the following changes
> merged in, unless there are any further comments at this point.

Yesterday pushed as commit 572676160d5639edc0ecb663147bd291841458d1.

> On Tue, 26 Mar 2013 17:33:46 +0000, "Joseph S. Myers" <joseph@codesourcery.com> wrote:
> > On Fri, 22 Mar 2013, Thomas Schwinge wrote:
> > 
> > > PowerPC -m64:
> > > 
> > > math/basic-test.out:
> > >     Failure:  double x = (double) (long double) sNaN, !issignaling
> > > 
> > > That is, this type cast -- which is a IEEE 754-2008 general-computational
> > > convertFormat operation (IEEE 754-2008, 5.4.2) -- does not turn the sNaN
> > > into a qNaN (whilst raising an INVALID exception; not checked here),
> > > which is contrary to IEEE 754-2008 5.1 and 7.2.  This I consider a
> > > compiler issue (powerpc-linux-gnu-gcc (Sourcery CodeBench 2012.09-92)
> > > 4.7.2).
> > 
> > Such a bug (assuming present in GCC trunk for 4.9) should be filed in GCC 
> > Bugzilla (and I suppose a new math-tests.h macro used to disable the test 
> > in question for older compilers).  Though I guess it might only be desired 
> > to change this for -fsignaling-nans.
> 
> I will [...] file in GCC Bugzilla, add its PR number to the
> math_tests.h comment (also for the 32-bit x86 issue discussed before):

Now both filed.  Just pushed as commit
74d87055bfeb31ea37bc2356d88c065c612e1c0e:

	* sysdeps/i386/fpu/math-tests.h (SNAN_TESTS_float)
	(SNAN_TESTS_double): Refer to GCC PR56831.
	* sysdeps/powerpc/math-tests.h (SNAN_TESTS_TYPE_CAST): Refer to
	GCC PR56828.

diff --git sysdeps/i386/fpu/math-tests.h sysdeps/i386/fpu/math-tests.h
index 00c5f6c..2245fc9 100644
--- sysdeps/i386/fpu/math-tests.h
+++ sysdeps/i386/fpu/math-tests.h
@@ -19,7 +19,8 @@
 /* On 32-bit x86, versions of GCC up to at least 4.8 are happy to use FPU load
    instructions for sNaN values, and loading a float or double sNaN value will
    already raise an INVALID exception as well as turn the sNaN into a qNaN,
-   rendering certain tests infeasible in this scenario.  */
+   rendering certain tests infeasible in this scenario.
+   <http://gcc.gnu.org/PR56831>.  */
 #define SNAN_TESTS_float	0
 #define SNAN_TESTS_double	0
 
diff --git sysdeps/powerpc/math-tests.h sysdeps/powerpc/math-tests.h
index 0f09610..d87dc9a 100644
--- sysdeps/powerpc/math-tests.h
+++ sysdeps/powerpc/math-tests.h
@@ -20,7 +20,8 @@
    a IEEE 754-2008 general-computational convertFormat operation (IEEE
    754-2008, 5.4.2) -- does not turn a sNaN into a qNaN (whilst raising an
    INVALID exception), which is contrary to IEEE 754-2008 5.1 and 7.2.  This
-   renders certain tests infeasible in this scenario.  */
+   renders certain tests infeasible in this scenario.
+   <http://gcc.gnu.org/PR56828>.  */
 #define SNAN_TESTS_TYPE_CAST	0
 
 #include_next <math-tests.h>


Grüße,
 Thomas

[-- Attachment #2: Type: application/pgp-signature, Size: 489 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2013-04-03 12:17 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <8762148l9v.fsf@schwinge.name>
2013-03-22 11:18 ` [attention machine maintainers] [PATCH] <math.h> issignaling Thomas Schwinge
2013-03-24 21:30   ` David Miller
2013-03-25  6:52     ` Thomas Schwinge
2013-03-25 18:39       ` David Miller
2013-03-25 15:54   ` Carlos O'Donell
2013-03-26 17:34   ` Joseph S. Myers
2013-03-28 12:16     ` Thomas Schwinge
2013-04-03 12:17       ` Thomas Schwinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).