public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2 0/5] x86 pseudo-normal numbers
@ 2020-12-23 11:55 Siddhesh Poyarekar
  2020-12-23 11:55 ` [PATCH v2 1/5] x86 long double: Support pseudo numbers in fpclassifyl Siddhesh Poyarekar
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Siddhesh Poyarekar @ 2020-12-23 11:55 UTC (permalink / raw)
  To: libc-alpha; +Cc: adhemerval.zanella, fweimer, joseph

Following is the patchset that harmonizes classification of
pseudo-normal numbers with gcc.  Pseudo-NaNs, Pseudo-Infinities and
unnormal numbers are considered as signaling NaN as per classification
since that is how they behave when used as operands in x86.

In summary, the patchset does the following:

- Update fpclassify to cater for pseudo-normal numbers
- Consolidate isnanl so that it can be used by isnanl as well as
  issignalingl.
- Update isnanl logic to return true for all pseudo-normal numbers
- Make issignalingl that returns true for all pseudo-normals.

Changes since v1:

- Consolidated the i386 and x86_64 versions of functions to x86.
- Update the test according to review comments

Siddhesh Poyarekar (5):
  x86 long double: Support pseudo numbers in fpclassifyl
  x86 long double: Support pseudo numbers in isnanl
  Partially revert 681900d29683722b1cb0a8e565a0585846ec5a61
  x86 long double: Consider pseudo numbers as signaling
  x86 long double: Add tests for pseudo normal numbers

 sysdeps/generic/nan-pseudo-number.h       |  27 +++++
 sysdeps/ieee754/ldbl-96/s_issignalingl.c  |   7 +-
 sysdeps/x86/fpu/Makefile                  |   3 +-
 sysdeps/x86/fpu/nan-pseudo-number.h       |  32 ++++++
 sysdeps/{i386 => x86}/fpu/s_fpclassifyl.c |   4 +
 sysdeps/{i386 => x86}/fpu/s_isnanl.c      |  12 +-
 sysdeps/x86/fpu/test-unnormal.c           | 132 ++++++++++++++++++++++
 sysdeps/x86/ldbl2mpn.c                    |   8 --
 sysdeps/x86/tst-ldbl-nonnormal-printf.c   |   5 +-
 sysdeps/x86_64/fpu/s_fpclassifyl.c        |   2 -
 sysdeps/x86_64/fpu/s_isnanl.c             |   1 -
 11 files changed, 211 insertions(+), 22 deletions(-)
 create mode 100644 sysdeps/generic/nan-pseudo-number.h
 create mode 100644 sysdeps/x86/fpu/nan-pseudo-number.h
 rename sysdeps/{i386 => x86}/fpu/s_fpclassifyl.c (87%)
 rename sysdeps/{i386 => x86}/fpu/s_isnanl.c (76%)
 create mode 100644 sysdeps/x86/fpu/test-unnormal.c
 delete mode 100644 sysdeps/x86_64/fpu/s_fpclassifyl.c
 delete mode 100644 sysdeps/x86_64/fpu/s_isnanl.c

-- 
2.29.2


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

* [PATCH v2 1/5] x86 long double: Support pseudo numbers in fpclassifyl
  2020-12-23 11:55 [PATCH v2 0/5] x86 pseudo-normal numbers Siddhesh Poyarekar
@ 2020-12-23 11:55 ` Siddhesh Poyarekar
  2020-12-23 17:59   ` Adhemerval Zanella
  2020-12-23 11:55 ` [PATCH v2 2/5] x86 long double: Support pseudo numbers in isnanl Siddhesh Poyarekar
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Siddhesh Poyarekar @ 2020-12-23 11:55 UTC (permalink / raw)
  To: libc-alpha; +Cc: adhemerval.zanella, fweimer, joseph

Also move sysdeps/i386/fpu/s_fpclassifyl.c to
sysdeps/x86/fpu/s_fpclassifyl.c and remove
sysdeps/x86_64/fpu/s_fpclassifyl.c
---
 sysdeps/{i386 => x86}/fpu/s_fpclassifyl.c | 4 ++++
 sysdeps/x86_64/fpu/s_fpclassifyl.c        | 2 --
 2 files changed, 4 insertions(+), 2 deletions(-)
 rename sysdeps/{i386 => x86}/fpu/s_fpclassifyl.c (87%)
 delete mode 100644 sysdeps/x86_64/fpu/s_fpclassifyl.c

diff --git a/sysdeps/i386/fpu/s_fpclassifyl.c b/sysdeps/x86/fpu/s_fpclassifyl.c
similarity index 87%
rename from sysdeps/i386/fpu/s_fpclassifyl.c
rename to sysdeps/x86/fpu/s_fpclassifyl.c
index 501312f51e..a48b7685c4 100644
--- a/sysdeps/i386/fpu/s_fpclassifyl.c
+++ b/sysdeps/x86/fpu/s_fpclassifyl.c
@@ -34,6 +34,10 @@ __fpclassifyl (long double x)
     retval = FP_ZERO;
   else if (ex == 0 && (hx & 0x80000000) == 0)
     retval = FP_SUBNORMAL;
+  /* Pseudo-normals, i.e. pseudo-zero, pseudo-infinity and un-normals.  They
+     behave like NaNs, so categorize them as such.  */
+  else if ((hx & 0x80000000) == 0)
+    retval = FP_NAN;
   else if (ex == 0x7fff)
     retval = ((hx & 0x7fffffff) | lx) != 0 ? FP_NAN : FP_INFINITE;
 
diff --git a/sysdeps/x86_64/fpu/s_fpclassifyl.c b/sysdeps/x86_64/fpu/s_fpclassifyl.c
deleted file mode 100644
index 856854b0f5..0000000000
--- a/sysdeps/x86_64/fpu/s_fpclassifyl.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#include <sysdeps/i386/fpu/s_fpclassifyl.c>
-
-- 
2.29.2


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

* [PATCH v2 2/5] x86 long double: Support pseudo numbers in isnanl
  2020-12-23 11:55 [PATCH v2 0/5] x86 pseudo-normal numbers Siddhesh Poyarekar
  2020-12-23 11:55 ` [PATCH v2 1/5] x86 long double: Support pseudo numbers in fpclassifyl Siddhesh Poyarekar
@ 2020-12-23 11:55 ` Siddhesh Poyarekar
  2020-12-23 18:03   ` Adhemerval Zanella
  2020-12-23 11:56 ` [PATCH v2 3/5] Partially revert 681900d29683722b1cb0a8e565a0585846ec5a61 Siddhesh Poyarekar
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Siddhesh Poyarekar @ 2020-12-23 11:55 UTC (permalink / raw)
  To: libc-alpha; +Cc: adhemerval.zanella, fweimer, joseph

This syncs up isnanl behaviour with gcc.  Also move the isnanl
implementation to sysdeps/x86 and remove the sysdeps/x86_64 version.
---
 sysdeps/{i386 => x86}/fpu/s_isnanl.c | 12 +++++++-----
 sysdeps/x86_64/fpu/s_isnanl.c        |  1 -
 2 files changed, 7 insertions(+), 6 deletions(-)
 rename sysdeps/{i386 => x86}/fpu/s_isnanl.c (76%)
 delete mode 100644 sysdeps/x86_64/fpu/s_isnanl.c

diff --git a/sysdeps/i386/fpu/s_isnanl.c b/sysdeps/x86/fpu/s_isnanl.c
similarity index 76%
rename from sysdeps/i386/fpu/s_isnanl.c
rename to sysdeps/x86/fpu/s_isnanl.c
index fb97317bc9..45541df08a 100644
--- a/sysdeps/i386/fpu/s_isnanl.c
+++ b/sysdeps/x86/fpu/s_isnanl.c
@@ -28,16 +28,18 @@ static char rcsid[] = "$NetBSD: $";
 
 int __isnanl(long double x)
 {
-	int32_t se,hx,lx;
+	int32_t se,hx,lx,pn;
 	GET_LDOUBLE_WORDS(se,hx,lx,x);
 	se = (se & 0x7fff) << 1;
-	/* The additional & 0x7fffffff is required because Intel's
-	   extended format has the normally implicit 1 explicit
-	   present.  Sigh!  */
+	/* Detect pseudo-normal numbers, i.e. exponent is non-zero and the top
+	   bit of the significand is not set.   */
+	pn = (uint32_t)((~hx & 0x80000000) & (se|(-se)))>>31;
+	/* Clear the significand bit when computing mantissa.  */
 	lx |= hx & 0x7fffffff;
 	se |= (uint32_t)(lx|(-lx))>>31;
 	se = 0xfffe - se;
-	return (int)((uint32_t)(se))>>16;
+
+	return (int)(((uint32_t)(se)) >> 16) | pn;
 }
 hidden_def (__isnanl)
 weak_alias (__isnanl, isnanl)
diff --git a/sysdeps/x86_64/fpu/s_isnanl.c b/sysdeps/x86_64/fpu/s_isnanl.c
deleted file mode 100644
index 06e69c3aeb..0000000000
--- a/sysdeps/x86_64/fpu/s_isnanl.c
+++ /dev/null
@@ -1 +0,0 @@
-#include <sysdeps/i386/fpu/s_isnanl.c>
-- 
2.29.2


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

* [PATCH v2 3/5] Partially revert 681900d29683722b1cb0a8e565a0585846ec5a61
  2020-12-23 11:55 [PATCH v2 0/5] x86 pseudo-normal numbers Siddhesh Poyarekar
  2020-12-23 11:55 ` [PATCH v2 1/5] x86 long double: Support pseudo numbers in fpclassifyl Siddhesh Poyarekar
  2020-12-23 11:55 ` [PATCH v2 2/5] x86 long double: Support pseudo numbers in isnanl Siddhesh Poyarekar
@ 2020-12-23 11:56 ` Siddhesh Poyarekar
  2020-12-23 12:09   ` Florian Weimer
  2020-12-23 11:56 ` [PATCH v2 4/5] x86 long double: Consider pseudo numbers as signaling Siddhesh Poyarekar
  2020-12-23 11:56 ` [PATCH v2 5/5] x86 long double: Add tests for pseudo normal numbers Siddhesh Poyarekar
  4 siblings, 1 reply; 10+ messages in thread
From: Siddhesh Poyarekar @ 2020-12-23 11:56 UTC (permalink / raw)
  To: libc-alpha; +Cc: adhemerval.zanella, fweimer, joseph

Do not attempt to fix the significand top bit in long double input
received in printf.  The code should never reach here because isnan
should now detect unnormals as NaN.  This is already a NOP for glibc
since it uses the gcc __builtin_isnan, which detects unnormals as NaN.
---
 sysdeps/x86/ldbl2mpn.c                  | 8 --------
 sysdeps/x86/tst-ldbl-nonnormal-printf.c | 5 +----
 2 files changed, 1 insertion(+), 12 deletions(-)

diff --git a/sysdeps/x86/ldbl2mpn.c b/sysdeps/x86/ldbl2mpn.c
index 23afedfb67..ec8464eef7 100644
--- a/sysdeps/x86/ldbl2mpn.c
+++ b/sysdeps/x86/ldbl2mpn.c
@@ -115,14 +115,6 @@ __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size,
 	   && res_ptr[N - 1] == 0)
     /* Pseudo zero.  */
     *expt = 0;
-  else
-    /* Unlike other floating point formats, the most significant bit
-       is explicit and expected to be set for normal numbers.  Set it
-       in case it is cleared in the input.  Otherwise, callers will
-       not be able to produce the expected multi-precision integer
-       layout by shifting.  */
-    res_ptr[N - 1] |= (mp_limb_t) 1 << (LDBL_MANT_DIG - 1
-					- ((N - 1) * BITS_PER_MP_LIMB));
 
   return N;
 }
diff --git a/sysdeps/x86/tst-ldbl-nonnormal-printf.c b/sysdeps/x86/tst-ldbl-nonnormal-printf.c
index 54381ece0b..2b513960a7 100644
--- a/sysdeps/x86/tst-ldbl-nonnormal-printf.c
+++ b/sysdeps/x86/tst-ldbl-nonnormal-printf.c
@@ -42,10 +42,7 @@ do_test (void)
   char buf[30];
   int ret = snprintf (buf, sizeof (buf), "%Lg", value);
   TEST_COMPARE (ret, strlen (buf));
-  if (strcmp (buf, "nan") != 0)
-    /* If snprintf does not recognize the non-normal number as a NaN,
-       it has added the missing explicit MSB.  */
-    TEST_COMPARE_STRING (buf, "3.02201e-4624");
+  TEST_COMPARE_STRING (buf, "nan");
   return 0;
 }
 
-- 
2.29.2


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

* [PATCH v2 4/5] x86 long double: Consider pseudo numbers as signaling
  2020-12-23 11:55 [PATCH v2 0/5] x86 pseudo-normal numbers Siddhesh Poyarekar
                   ` (2 preceding siblings ...)
  2020-12-23 11:56 ` [PATCH v2 3/5] Partially revert 681900d29683722b1cb0a8e565a0585846ec5a61 Siddhesh Poyarekar
@ 2020-12-23 11:56 ` Siddhesh Poyarekar
  2020-12-23 18:14   ` Adhemerval Zanella
  2020-12-23 11:56 ` [PATCH v2 5/5] x86 long double: Add tests for pseudo normal numbers Siddhesh Poyarekar
  4 siblings, 1 reply; 10+ messages in thread
From: Siddhesh Poyarekar @ 2020-12-23 11:56 UTC (permalink / raw)
  To: libc-alpha; +Cc: adhemerval.zanella, fweimer, joseph

Add support to treat pseudo-numbers specially and implement x86
version to consider all of them as signaling.
---
 sysdeps/generic/nan-pseudo-number.h      | 27 ++++++++++++++++++++
 sysdeps/ieee754/ldbl-96/s_issignalingl.c |  7 +++++-
 sysdeps/x86/fpu/nan-pseudo-number.h      | 32 ++++++++++++++++++++++++
 3 files changed, 65 insertions(+), 1 deletion(-)
 create mode 100644 sysdeps/generic/nan-pseudo-number.h
 create mode 100644 sysdeps/x86/fpu/nan-pseudo-number.h

diff --git a/sysdeps/generic/nan-pseudo-number.h b/sysdeps/generic/nan-pseudo-number.h
new file mode 100644
index 0000000000..ce1176a208
--- /dev/null
+++ b/sysdeps/generic/nan-pseudo-number.h
@@ -0,0 +1,27 @@
+/* Pseudo-normal number handling.  Generic version.
+   Copyright (C) 2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef NAN_PSEUDO_NUMBER_H
+#define NAN_PSEUDO_NUMBER_H	1
+
+/* Define this macro to 1 and provide an definition for IS_PSEUDO_SIGNALING if
+   pseudo-normal numbers need special handling.  */
+#define HANDLE_PSEUDO_NUMBERS 0
+#define IS_PSEUDO_SIGNALING(x) 0
+
+#endif /* nan-pseudo-number.h */
diff --git a/sysdeps/ieee754/ldbl-96/s_issignalingl.c b/sysdeps/ieee754/ldbl-96/s_issignalingl.c
index ec542ad468..fff6a85932 100644
--- a/sysdeps/ieee754/ldbl-96/s_issignalingl.c
+++ b/sysdeps/ieee754/ldbl-96/s_issignalingl.c
@@ -19,12 +19,14 @@
 #include <math.h>
 #include <math_private.h>
 #include <nan-high-order-bit.h>
+#include <nan-pseudo-number.h>
 
 int
 __issignalingl (long double x)
 {
   uint32_t exi, hxi, lxi;
   GET_LDOUBLE_WORDS (exi, hxi, lxi, x);
+  int ret = 0;
 #if HIGH_ORDER_BIT_IS_SET_FOR_SNAN
 # error not implemented
 #else
@@ -36,9 +38,12 @@ __issignalingl (long double x)
   hxi |= (lxi | -lxi) >> 31;
   /* We do not recognize a pseudo NaN as sNaN; they're invalid on 80387 and
      later.  */
+#if HANDLE_PSEUDO_NUMBERS
+  ret = IS_PSEUDO_SIGNALING(x);
+#endif
   /* 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);
+  return ret || (((exi & 0x7fff) == 0x7fff) && (hxi > 0xc0000000));
 #endif
 }
 libm_hidden_def (__issignalingl)
diff --git a/sysdeps/x86/fpu/nan-pseudo-number.h b/sysdeps/x86/fpu/nan-pseudo-number.h
new file mode 100644
index 0000000000..9cc37a3eee
--- /dev/null
+++ b/sysdeps/x86/fpu/nan-pseudo-number.h
@@ -0,0 +1,32 @@
+/* Pseudo-normal number handling.  x86 version.
+   Copyright (C) 2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef NAN_PSEUDO_NUMBER_H
+#define NAN_PSEUDO_NUMBER_H	1
+
+#define HANDLE_PSEUDO_NUMBERS 1
+/* A pseudo-normal number (that is not pseudo-denormal) has a non-zero exponent
+   and the MSB of significand is clear.  All pseudo-normal numbers are deemed
+   signaling.  */
+#define IS_PSEUDO_SIGNALING(x) ({					      \
+  uint32_t exi, hxi, lxi __attribute__ ((unused));			      \
+  GET_LDOUBLE_WORDS (exi, hxi, lxi, x);					      \
+  ((exi & 0x7fff) && ((hxi & 0x80000000) == 0));			      \
+})
+
+#endif /* nan-pseudo-number.h */
-- 
2.29.2


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

* [PATCH v2 5/5] x86 long double: Add tests for pseudo normal numbers
  2020-12-23 11:55 [PATCH v2 0/5] x86 pseudo-normal numbers Siddhesh Poyarekar
                   ` (3 preceding siblings ...)
  2020-12-23 11:56 ` [PATCH v2 4/5] x86 long double: Consider pseudo numbers as signaling Siddhesh Poyarekar
@ 2020-12-23 11:56 ` Siddhesh Poyarekar
  4 siblings, 0 replies; 10+ messages in thread
From: Siddhesh Poyarekar @ 2020-12-23 11:56 UTC (permalink / raw)
  To: libc-alpha; +Cc: adhemerval.zanella, fweimer, joseph

Add some tests for fpclassify, isnanl, isinfl and issignaling.
---
 sysdeps/x86/fpu/Makefile        |   3 +-
 sysdeps/x86/fpu/test-unnormal.c | 132 ++++++++++++++++++++++++++++++++
 2 files changed, 134 insertions(+), 1 deletion(-)
 create mode 100644 sysdeps/x86/fpu/test-unnormal.c

diff --git a/sysdeps/x86/fpu/Makefile b/sysdeps/x86/fpu/Makefile
index 600e42c3db..e77de56d14 100644
--- a/sysdeps/x86/fpu/Makefile
+++ b/sysdeps/x86/fpu/Makefile
@@ -4,11 +4,12 @@ CPPFLAGS += -I../soft-fp
 
 libm-support += powl_helper
 tests += test-fenv-sse test-fenv-clear-sse test-fenv-x87 test-fenv-sse-2 \
-	 test-flt-eval-method-387 test-flt-eval-method-sse
+	 test-flt-eval-method-387 test-flt-eval-method-sse test-unnormal
 CFLAGS-test-fenv-sse.c += -msse2 -mfpmath=sse
 CFLAGS-test-fenv-clear-sse.c += -msse2 -mfpmath=sse
 CFLAGS-test-fenv-sse-2.c += -msse2 -mfpmath=sse
 CFLAGS-test-flt-eval-method-387.c += -fexcess-precision=standard -mfpmath=387
 CFLAGS-test-flt-eval-method-sse.c += -fexcess-precision=standard -msse2 \
 				     -mfpmath=sse
+CFLAGS-test-unnormal.c += -fsignaling-nans -std=c2x
 endif
diff --git a/sysdeps/x86/fpu/test-unnormal.c b/sysdeps/x86/fpu/test-unnormal.c
new file mode 100644
index 0000000000..a6baa01802
--- /dev/null
+++ b/sysdeps/x86/fpu/test-unnormal.c
@@ -0,0 +1,132 @@
+/* Test long double classification with x86 pseudo normal numbers.
+   Copyright (C) 2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+#include <math_ldbl.h>
+#include <support/test-driver.h>
+#include <support/check.h>
+
+/* If we need to add regular NaNs here then we need another member specifying
+   whether the NaN is signaling and then issignaling test should be updated to
+   use it.  Additionally, all pseudo-numbers should be classified as
+   signaling.  */
+struct tests
+{
+  ieee_long_double_shape_type d;
+  int class;
+} inputs[] = {
+      /* Normal.  */
+      {
+	.d.parts.lsw = 0x00000400,
+	.d.parts.msw = 0x00000000,
+	.d.parts.sign_exponent = 0x0400,
+	.class = FP_NAN
+      },
+      {
+	.d.parts.lsw = 0x00000400,
+	.d.parts.msw = 0xf0000000,
+	.d.parts.sign_exponent = 0x0400,
+	.class = FP_NORMAL
+      },
+      /* Pseudo-infinite.  */
+      {
+	.d.parts.lsw = 0x00000000,
+	.d.parts.msw = 0x00000000,
+	.d.parts.sign_exponent = 0x7fff,
+	.class = FP_NAN
+      },
+      {
+	.d.parts.lsw = 0x00000000,
+	.d.parts.msw = 0x80000000,
+	.d.parts.sign_exponent = 0x7fff,
+	.class = FP_INFINITE
+      },
+      /* Pseudo-zero.  */
+      {
+	.d.parts.lsw = 0x00000000,
+	.d.parts.msw = 0x00000000,
+	.d.parts.sign_exponent = 0x0100,
+	.class = FP_NAN
+      },
+      {
+	.d.parts.lsw = 0x00000000,
+	.d.parts.msw = 0x00000000,
+	.d.parts.sign_exponent = 0x0000,
+	.class = FP_ZERO
+      },
+};
+
+typedef void (*testfunc_t) (long double, int);
+
+static int
+test_func (const char *testname, testfunc_t testfunc)
+{
+  verbose_printf ("* %s:\n", testname);
+
+  for (int i = 0; i < sizeof (inputs)/sizeof (struct tests); i++)
+    {
+      verbose_printf ("Testing 0x%04x %08x %08x\n",
+		      inputs[i].d.parts.sign_exponent, inputs[i].d.parts.msw,
+		      inputs[i].d.parts.lsw);
+      testfunc (inputs[i].d.value, inputs[i].class);
+    }
+
+  return 0;
+}
+
+static void
+test_fpclassify (long double value, int class)
+{
+  TEST_COMPARE (fpclassify (value), class);
+}
+
+static void
+test_isinf (long double value, int class)
+{
+  TEST_COMPARE ((isinf (value) != 0), (class == FP_INFINITE));
+}
+
+static void
+test_isnan (long double value, int class)
+{
+  TEST_COMPARE ((isnan (value) != 0), (class == FP_NAN));
+}
+
+static void
+test_issignaling (long double value, int class)
+{
+  TEST_COMPARE ((issignaling (value) != 0), (class == FP_NAN));
+}
+
+int
+do_test (void)
+{
+  int ret = 0;
+
+  test_func ("fpclassify", test_fpclassify);
+  test_func ("isinf", test_isinf);
+  test_func ("isnan", test_isnan);
+  test_func ("issignaling", test_issignaling);
+
+  return ret;
+}
+
+#include <support/test-driver.c>
-- 
2.29.2


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

* Re: [PATCH v2 3/5] Partially revert 681900d29683722b1cb0a8e565a0585846ec5a61
  2020-12-23 11:56 ` [PATCH v2 3/5] Partially revert 681900d29683722b1cb0a8e565a0585846ec5a61 Siddhesh Poyarekar
@ 2020-12-23 12:09   ` Florian Weimer
  0 siblings, 0 replies; 10+ messages in thread
From: Florian Weimer @ 2020-12-23 12:09 UTC (permalink / raw)
  To: Siddhesh Poyarekar; +Cc: libc-alpha, adhemerval.zanella, joseph

* Siddhesh Poyarekar:

> Do not attempt to fix the significand top bit in long double input
> received in printf.  The code should never reach here because isnan
> should now detect unnormals as NaN.  This is already a NOP for glibc
> since it uses the gcc __builtin_isnan, which detects unnormals as NaN.

This looks okay to me, thanks.

Florian
-- 
Red Hat GmbH, https://de.redhat.com/ , Registered seat: Grasbrunn,
Commercial register: Amtsgericht Muenchen, HRB 153243,
Managing Directors: Charles Cachera, Brian Klemm, Laurie Krebs, Michael O'Neill


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

* Re: [PATCH v2 1/5] x86 long double: Support pseudo numbers in fpclassifyl
  2020-12-23 11:55 ` [PATCH v2 1/5] x86 long double: Support pseudo numbers in fpclassifyl Siddhesh Poyarekar
@ 2020-12-23 17:59   ` Adhemerval Zanella
  0 siblings, 0 replies; 10+ messages in thread
From: Adhemerval Zanella @ 2020-12-23 17:59 UTC (permalink / raw)
  To: Siddhesh Poyarekar, libc-alpha; +Cc: fweimer, joseph



On 23/12/2020 08:55, Siddhesh Poyarekar wrote:
> Also move sysdeps/i386/fpu/s_fpclassifyl.c to
> sysdeps/x86/fpu/s_fpclassifyl.c and remove
> sysdeps/x86_64/fpu/s_fpclassifyl.c

LGTM, thanks.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>

> ---
>  sysdeps/{i386 => x86}/fpu/s_fpclassifyl.c | 4 ++++
>  sysdeps/x86_64/fpu/s_fpclassifyl.c        | 2 --
>  2 files changed, 4 insertions(+), 2 deletions(-)
>  rename sysdeps/{i386 => x86}/fpu/s_fpclassifyl.c (87%)
>  delete mode 100644 sysdeps/x86_64/fpu/s_fpclassifyl.c
> 
> diff --git a/sysdeps/i386/fpu/s_fpclassifyl.c b/sysdeps/x86/fpu/s_fpclassifyl.c
> similarity index 87%
> rename from sysdeps/i386/fpu/s_fpclassifyl.c
> rename to sysdeps/x86/fpu/s_fpclassifyl.c
> index 501312f51e..a48b7685c4 100644
> --- a/sysdeps/i386/fpu/s_fpclassifyl.c
> +++ b/sysdeps/x86/fpu/s_fpclassifyl.c
> @@ -34,6 +34,10 @@ __fpclassifyl (long double x)
>      retval = FP_ZERO;
>    else if (ex == 0 && (hx & 0x80000000) == 0)
>      retval = FP_SUBNORMAL;
> +  /* Pseudo-normals, i.e. pseudo-zero, pseudo-infinity and un-normals.  They
> +     behave like NaNs, so categorize them as such.  */
> +  else if ((hx & 0x80000000) == 0)
> +    retval = FP_NAN;
>    else if (ex == 0x7fff)
>      retval = ((hx & 0x7fffffff) | lx) != 0 ? FP_NAN : FP_INFINITE;
>  
> diff --git a/sysdeps/x86_64/fpu/s_fpclassifyl.c b/sysdeps/x86_64/fpu/s_fpclassifyl.c
> deleted file mode 100644
> index 856854b0f5..0000000000
> --- a/sysdeps/x86_64/fpu/s_fpclassifyl.c
> +++ /dev/null
> @@ -1,2 +0,0 @@
> -#include <sysdeps/i386/fpu/s_fpclassifyl.c>
> -
> 

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

* Re: [PATCH v2 2/5] x86 long double: Support pseudo numbers in isnanl
  2020-12-23 11:55 ` [PATCH v2 2/5] x86 long double: Support pseudo numbers in isnanl Siddhesh Poyarekar
@ 2020-12-23 18:03   ` Adhemerval Zanella
  0 siblings, 0 replies; 10+ messages in thread
From: Adhemerval Zanella @ 2020-12-23 18:03 UTC (permalink / raw)
  To: Siddhesh Poyarekar, libc-alpha; +Cc: fweimer, joseph



On 23/12/2020 08:55, Siddhesh Poyarekar wrote:
> This syncs up isnanl behaviour with gcc.  Also move the isnanl
> implementation to sysdeps/x86 and remove the sysdeps/x86_64 version.

LGTM, thanks.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>

> ---
>  sysdeps/{i386 => x86}/fpu/s_isnanl.c | 12 +++++++-----
>  sysdeps/x86_64/fpu/s_isnanl.c        |  1 -
>  2 files changed, 7 insertions(+), 6 deletions(-)
>  rename sysdeps/{i386 => x86}/fpu/s_isnanl.c (76%)
>  delete mode 100644 sysdeps/x86_64/fpu/s_isnanl.c
> 
> diff --git a/sysdeps/i386/fpu/s_isnanl.c b/sysdeps/x86/fpu/s_isnanl.c
> similarity index 76%
> rename from sysdeps/i386/fpu/s_isnanl.c
> rename to sysdeps/x86/fpu/s_isnanl.c
> index fb97317bc9..45541df08a 100644
> --- a/sysdeps/i386/fpu/s_isnanl.c
> +++ b/sysdeps/x86/fpu/s_isnanl.c
> @@ -28,16 +28,18 @@ static char rcsid[] = "$NetBSD: $";
>  
>  int __isnanl(long double x)
>  {
> -	int32_t se,hx,lx;
> +	int32_t se,hx,lx,pn;
>  	GET_LDOUBLE_WORDS(se,hx,lx,x);
>  	se = (se & 0x7fff) << 1;
> -	/* The additional & 0x7fffffff is required because Intel's
> -	   extended format has the normally implicit 1 explicit
> -	   present.  Sigh!  */
> +	/* Detect pseudo-normal numbers, i.e. exponent is non-zero and the top
> +	   bit of the significand is not set.   */
> +	pn = (uint32_t)((~hx & 0x80000000) & (se|(-se)))>>31;
> +	/* Clear the significand bit when computing mantissa.  */
>  	lx |= hx & 0x7fffffff;
>  	se |= (uint32_t)(lx|(-lx))>>31;
>  	se = 0xfffe - se;
> -	return (int)((uint32_t)(se))>>16;
> +
> +	return (int)(((uint32_t)(se)) >> 16) | pn;
>  }
>  hidden_def (__isnanl)
>  weak_alias (__isnanl, isnanl)
> diff --git a/sysdeps/x86_64/fpu/s_isnanl.c b/sysdeps/x86_64/fpu/s_isnanl.c
> deleted file mode 100644
> index 06e69c3aeb..0000000000
> --- a/sysdeps/x86_64/fpu/s_isnanl.c
> +++ /dev/null
> @@ -1 +0,0 @@
> -#include <sysdeps/i386/fpu/s_isnanl.c>
> 

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

* Re: [PATCH v2 4/5] x86 long double: Consider pseudo numbers as signaling
  2020-12-23 11:56 ` [PATCH v2 4/5] x86 long double: Consider pseudo numbers as signaling Siddhesh Poyarekar
@ 2020-12-23 18:14   ` Adhemerval Zanella
  0 siblings, 0 replies; 10+ messages in thread
From: Adhemerval Zanella @ 2020-12-23 18:14 UTC (permalink / raw)
  To: Siddhesh Poyarekar, libc-alpha; +Cc: fweimer, joseph



On 23/12/2020 08:56, Siddhesh Poyarekar wrote:
> Add support to treat pseudo-numbers specially and implement x86
> version to consider all of them as signaling.
> ---
>  sysdeps/generic/nan-pseudo-number.h      | 27 ++++++++++++++++++++
>  sysdeps/ieee754/ldbl-96/s_issignalingl.c |  7 +++++-
>  sysdeps/x86/fpu/nan-pseudo-number.h      | 32 ++++++++++++++++++++++++
>  3 files changed, 65 insertions(+), 1 deletion(-)
>  create mode 100644 sysdeps/generic/nan-pseudo-number.h
>  create mode 100644 sysdeps/x86/fpu/nan-pseudo-number.h
> 
> diff --git a/sysdeps/generic/nan-pseudo-number.h b/sysdeps/generic/nan-pseudo-number.h
> new file mode 100644
> index 0000000000..ce1176a208
> --- /dev/null
> +++ b/sysdeps/generic/nan-pseudo-number.h
> @@ -0,0 +1,27 @@
> +/* Pseudo-normal number handling.  Generic version.
> +   Copyright (C) 2020 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef NAN_PSEUDO_NUMBER_H
> +#define NAN_PSEUDO_NUMBER_H	1
> +
> +/* Define this macro to 1 and provide an definition for IS_PSEUDO_SIGNALING if
> +   pseudo-normal numbers need special handling.  */
> +#define HANDLE_PSEUDO_NUMBERS 0
> +#define IS_PSEUDO_SIGNALING(x) 0
> +
> +#endif /* nan-pseudo-number.h */
> diff --git a/sysdeps/ieee754/ldbl-96/s_issignalingl.c b/sysdeps/ieee754/ldbl-96/s_issignalingl.c
> index ec542ad468..fff6a85932 100644
> --- a/sysdeps/ieee754/ldbl-96/s_issignalingl.c
> +++ b/sysdeps/ieee754/ldbl-96/s_issignalingl.c
> @@ -19,12 +19,14 @@
>  #include <math.h>
>  #include <math_private.h>
>  #include <nan-high-order-bit.h>
> +#include <nan-pseudo-number.h>
>  
>  int
>  __issignalingl (long double x)
>  {
>    uint32_t exi, hxi, lxi;
>    GET_LDOUBLE_WORDS (exi, hxi, lxi, x);
> +  int ret = 0;
>  #if HIGH_ORDER_BIT_IS_SET_FOR_SNAN
>  # error not implemented
>  #else
> @@ -36,9 +38,12 @@ __issignalingl (long double x)
>    hxi |= (lxi | -lxi) >> 31;
>    /* We do not recognize a pseudo NaN as sNaN; they're invalid on 80387 and
>       later.  */
> +#if HANDLE_PSEUDO_NUMBERS
> +  ret = IS_PSEUDO_SIGNALING(x);
> +#endif
>    /* 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);
> +  return ret || (((exi & 0x7fff) == 0x7fff) && (hxi > 0xc0000000));
>  #endif
>  }
>  libm_hidden_def (__issignalingl)
> diff --git a/sysdeps/x86/fpu/nan-pseudo-number.h b/sysdeps/x86/fpu/nan-pseudo-number.h
> new file mode 100644
> index 0000000000..9cc37a3eee
> --- /dev/null
> +++ b/sysdeps/x86/fpu/nan-pseudo-number.h
> @@ -0,0 +1,32 @@
> +/* Pseudo-normal number handling.  x86 version.
> +   Copyright (C) 2020 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef NAN_PSEUDO_NUMBER_H
> +#define NAN_PSEUDO_NUMBER_H	1
> +
> +#define HANDLE_PSEUDO_NUMBERS 1
> +/* A pseudo-normal number (that is not pseudo-denormal) has a non-zero exponent
> +   and the MSB of significand is clear.  All pseudo-normal numbers are deemed
> +   signaling.  */
> +#define IS_PSEUDO_SIGNALING(x) ({					      \
> +  uint32_t exi, hxi, lxi __attribute__ ((unused));			      \
> +  GET_LDOUBLE_WORDS (exi, hxi, lxi, x);					      \
> +  ((exi & 0x7fff) && ((hxi & 0x80000000) == 0));			      \
> +})
> +
> +#endif /* nan-pseudo-number.h */
> 

Maybe a static inline function would be better? Something like:

  static inline int pseudo_signaling (uint32_t exi, uint32_t hxi)
  {
    return (exi & 0x7fff) && (hxi & 0x80000000) == 0;
  }

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

end of thread, other threads:[~2020-12-23 18:14 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-23 11:55 [PATCH v2 0/5] x86 pseudo-normal numbers Siddhesh Poyarekar
2020-12-23 11:55 ` [PATCH v2 1/5] x86 long double: Support pseudo numbers in fpclassifyl Siddhesh Poyarekar
2020-12-23 17:59   ` Adhemerval Zanella
2020-12-23 11:55 ` [PATCH v2 2/5] x86 long double: Support pseudo numbers in isnanl Siddhesh Poyarekar
2020-12-23 18:03   ` Adhemerval Zanella
2020-12-23 11:56 ` [PATCH v2 3/5] Partially revert 681900d29683722b1cb0a8e565a0585846ec5a61 Siddhesh Poyarekar
2020-12-23 12:09   ` Florian Weimer
2020-12-23 11:56 ` [PATCH v2 4/5] x86 long double: Consider pseudo numbers as signaling Siddhesh Poyarekar
2020-12-23 18:14   ` Adhemerval Zanella
2020-12-23 11:56 ` [PATCH v2 5/5] x86 long double: Add tests for pseudo normal numbers Siddhesh Poyarekar

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).