[PATCH 5/5] x86 long double: Add tests for pseudo normal numbers

Siddhesh Poyarekar siddhesh@sourceware.org
Tue Dec 15 14:13:39 GMT 2020


Add some tests for fpclassify, isnanl, isinfl and issignaling.
---
 sysdeps/x86/fpu/Makefile        |   3 +-
 sysdeps/x86/fpu/test-unnormal.c | 196 ++++++++++++++++++++++++++++++++
 2 files changed, 198 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..fc65d9290f
--- /dev/null
+++ b/sysdeps/x86/fpu/test-unnormal.c
@@ -0,0 +1,196 @@
+/* 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>
+
+struct tests
+{
+  const char *val;
+  int class;
+} inputs[] = {
+      /* Normal.  */
+      {"\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04", FP_NAN},
+      {"\x00\x04\x00\x00\x00\x00\x00\xf0\x00\x04", FP_NORMAL},
+      /* Pseudo-infinite.  */
+      {"\x00\x00\x00\x00\x00\x00\x00\x00\xff\x7f", FP_NAN},
+      {"\x00\x00\x00\x00\x00\x00\x00\x80\xff\x7f", FP_INFINITE},
+      /* Pseudo-zero.  */
+      {"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", FP_NAN},
+      {"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", FP_ZERO},
+};
+
+const char *classes[5];
+#define stringify(N) #N
+
+static void
+initialize (void)
+{
+  classes[FP_NAN] = stringify(FP_NAN);
+  classes[FP_INFINITE] = stringify(FP_INFINITY);
+  classes[FP_ZERO] = stringify(FP_ZERO);
+  classes[FP_SUBNORMAL] = stringify(FP_SUBNORMAL);
+  classes[FP_NORMAL] = stringify(FP_NORMAL);
+}
+
+static void
+unnormal_str (const char *val, char *ret)
+{
+  for (int i = 9; i >= 0; i--)
+    {
+      if (i == 7 || i == 3)
+	*ret++ = ' ';
+      snprintf(ret, 3, "%02x", (unsigned char) val[i]);
+      ret += 2;
+    }
+}
+
+static int
+test_fpclassify (void)
+{
+  int ret = 0;
+
+  printf ("* fpclassify tests:\n");
+  for (int i = 0; i < sizeof (inputs)/sizeof (struct tests); i++)
+    {
+      long double value;
+      char buf[22];
+
+      memcpy (&value, inputs[i].val, 10);
+      unnormal_str(inputs[i].val, buf);
+      int class = fpclassify(value);
+
+      if (class != inputs[i].class)
+	{
+	  printf ("0x%s: got %s, expected %s\n", buf,
+		  classes[fpclassify(value)],
+		  classes[inputs[i].class]);
+	  ret |= 1;
+	}
+      else
+	printf ("0x%s: OK\n", buf);
+    }
+  return ret;
+}
+
+static int
+test_isinf (void)
+{
+  int ret = 0;
+
+  printf ("* isinfl tests:\n");
+  for (int i = 0; i < sizeof (inputs)/sizeof (struct tests); i++)
+    {
+      long double value;
+      char buf[22];
+
+      memcpy (&value, inputs[i].val, 10);
+      unnormal_str(inputs[i].val, buf);
+      int inf = isinf (value);
+
+      if ((inputs[i].class == FP_INFINITE && inf)
+	  || (inputs[i].class != FP_INFINITE && !inf))
+	printf ("0x%s: OK\n", buf);
+      else
+	{
+	  printf ("0x%s: got %s, expected %s\n", buf,
+		  inf ? "INFINITE" : "NOT INFINITE",
+		  classes[inputs[i].class]);
+	  ret |= 1;
+	}
+    }
+
+  return ret;
+}
+
+static int
+test_isnan (void)
+{
+  int ret = 0;
+
+  printf ("* isnanl tests:\n");
+  for (int i = 0; i < sizeof (inputs)/sizeof (struct tests); i++)
+    {
+      long double value;
+      char buf[22];
+
+      memcpy (&value, inputs[i].val, 10);
+      unnormal_str(inputs[i].val, buf);
+      int nan = isnan (value);
+
+      if ((inputs[i].class == FP_NAN && nan)
+	  || (inputs[i].class != FP_NAN && !nan))
+	printf ("0x%s: OK\n", buf);
+      else
+	{
+	  printf ("0x%s: got %s, expected %s\n", buf,
+		  nan ? "NAN" : "NOT NAN",
+		  classes[inputs[i].class]);
+	  ret |= 1;
+	}
+    }
+  return ret;
+}
+
+static int
+test_issignaling (void)
+{
+  int ret = 0;
+
+  printf ("* issignaling tests:\n");
+  for (int i = 0; i < sizeof (inputs)/sizeof (struct tests); i++)
+    {
+      long double value;
+      char buf[22];
+
+      memcpy (&value, inputs[i].val, 10);
+      unnormal_str(inputs[i].val, buf);
+      int signaling = issignaling (value);
+
+      if ((inputs[i].class == FP_NAN && signaling)
+	  || (inputs[i].class != FP_NAN && !signaling))
+	printf ("0x%s: OK\n", buf);
+      else
+	{
+	  printf ("0x%s: got %s, expected %s\n", buf,
+		  signaling ? "SIGNALING" : "NOT SIGNALING",
+		  classes[inputs[i].class]);
+	  ret |= 1;
+	}
+    }
+  return ret;
+}
+
+int
+do_test (void)
+{
+  int ret = 0;
+
+  initialize ();
+
+  ret |= test_fpclassify ();
+  ret |= test_isinf ();
+  ret |= test_isnan ();
+  ret |= test_issignaling ();
+
+  return ret;
+}
+
+#include <support/test-driver.c>
-- 
2.29.2



More information about the Libc-alpha mailing list