public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2 00/10] Improve rounding to interger function for C23
@ 2024-04-03 12:11 Adhemerval Zanella
  2024-04-03 12:11 ` [PATCH v2 01/10] math: Add test to check if ceil raise inexact floating-point exception Adhemerval Zanella
                   ` (10 more replies)
  0 siblings, 11 replies; 21+ messages in thread
From: Adhemerval Zanella @ 2024-04-03 12:11 UTC (permalink / raw)
  To: libc-alpha; +Cc: H . J . Lu

As indicated by GCC documentation [1], ISO C23 does not allow that C
bindings ceil, floor, round, and trunc (in all floating point formats)
to raise inexact exceptions (different than ISO C99/C11 where this is
allowed).

A recent MIPS patch to used some arch-specific instructions raised this
issue [1] and it was not caught because there was no proper testing. By
adding the missing tests, some implementations do indeed raise inexact
exceptions. 

The generic implementation all uses integer operation, so they are not
subject to this issue. The powerpc (for power4 and lower) and the riscv
avoid the inexact exception by disabling/enabling exceptions. The x86
uses some arch-specific implementation for long double and on i386 (due
to the use of x87 instruction).

Instead of adding newer symbols depending on the required standard
version, the patchset adapts the faulty ones to avoid raising the
inexact exception. The x86 version already saves/restore the floating
point status, so I think it is unlikely the patch would yield much
performance difference (I did not do any performance analysis on whether
a generic implementation would yield better performance).

I checked on powerpc, powerpc64, aarch64, armhf, x86, and did some
regression checks on riscv.

[1] https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-fno-fp-int-builtin-inexact
[2] https://sourceware.org/pipermail/libc-alpha/2023-December/153528.html

Changes from v1:
* Updated Copyright years.

Adhemerval Zanella (10):
  math: Add test to check if ceil raise inexact floating-point exception
  math: Add test to check if floor raise inexact floating-point
    exception
  math: Add test to check if trunc raise inexact floating-point
    exception
  math: Add test to check if round raise inexact floating-point
    exception
  x86: Do not raise inexact exception on ceill
  x86: Do not raise inexact exception on floorl
  x86: Do not raise inexact exception on truncl
  x86: Do not raise inexact exception on floor/floorf
  i386: Do not raise inexact exception on ceil/ceilf
  i386: Do not raise inexact exception on trunc/truncf

 math/Makefile                                 | 17 ++++
 math/test-ceil-except-2.c                     | 67 +++++++++++++++
 math/test-ceil-except.c                       | 85 +++++++++++++++++++
 math/test-floor-except-2.c                    | 67 +++++++++++++++
 math/test-floor-except.c                      | 85 +++++++++++++++++++
 math/test-round-except-2.c                    | 67 +++++++++++++++
 math/test-round-except.c                      | 85 +++++++++++++++++++
 math/test-trunc-except-2.c                    | 67 +++++++++++++++
 math/test-trunc-except.c                      | 85 +++++++++++++++++++
 sysdeps/i386/fpu/s_ceil.S                     | 34 --------
 sysdeps/i386/fpu/s_ceil.c                     | 38 +++++++++
 sysdeps/i386/fpu/s_ceilf.S                    | 34 --------
 sysdeps/i386/fpu/s_ceilf.c                    | 38 +++++++++
 sysdeps/i386/fpu/s_ceill.S                    | 39 ---------
 sysdeps/i386/fpu/s_floor.S                    | 34 --------
 sysdeps/i386/fpu/s_floor.c                    | 38 +++++++++
 sysdeps/i386/fpu/s_floorf.S                   | 34 --------
 sysdeps/i386/fpu/s_floorf.c                   | 38 +++++++++
 sysdeps/i386/fpu/s_floorl.S                   | 39 ---------
 sysdeps/i386/fpu/{s_trunc.S => s_trunc.c}     | 37 ++++----
 sysdeps/i386/fpu/{s_truncf.S => s_truncf.c}   | 37 ++++----
 .../fpu/s_truncl.S => x86/fpu/s_ceill.c}      | 38 +++++----
 sysdeps/x86/fpu/s_floorl.c                    | 38 +++++++++
 .../fpu/s_truncl.S => x86/fpu/s_truncl.c}     | 40 +++++----
 sysdeps/x86_64/fpu/s_ceill.S                  | 34 --------
 sysdeps/x86_64/fpu/s_floorl.S                 | 33 -------
 26 files changed, 892 insertions(+), 356 deletions(-)
 create mode 100644 math/test-ceil-except-2.c
 create mode 100644 math/test-ceil-except.c
 create mode 100644 math/test-floor-except-2.c
 create mode 100644 math/test-floor-except.c
 create mode 100644 math/test-round-except-2.c
 create mode 100644 math/test-round-except.c
 create mode 100644 math/test-trunc-except-2.c
 create mode 100644 math/test-trunc-except.c
 delete mode 100644 sysdeps/i386/fpu/s_ceil.S
 create mode 100644 sysdeps/i386/fpu/s_ceil.c
 delete mode 100644 sysdeps/i386/fpu/s_ceilf.S
 create mode 100644 sysdeps/i386/fpu/s_ceilf.c
 delete mode 100644 sysdeps/i386/fpu/s_ceill.S
 delete mode 100644 sysdeps/i386/fpu/s_floor.S
 create mode 100644 sysdeps/i386/fpu/s_floor.c
 delete mode 100644 sysdeps/i386/fpu/s_floorf.S
 create mode 100644 sysdeps/i386/fpu/s_floorf.c
 delete mode 100644 sysdeps/i386/fpu/s_floorl.S
 rename sysdeps/i386/fpu/{s_trunc.S => s_trunc.c} (61%)
 rename sysdeps/i386/fpu/{s_truncf.S => s_truncf.c} (61%)
 rename sysdeps/{x86_64/fpu/s_truncl.S => x86/fpu/s_ceill.c} (57%)
 create mode 100644 sysdeps/x86/fpu/s_floorl.c
 rename sysdeps/{i386/fpu/s_truncl.S => x86/fpu/s_truncl.c} (61%)
 delete mode 100644 sysdeps/x86_64/fpu/s_ceill.S
 delete mode 100644 sysdeps/x86_64/fpu/s_floorl.S

-- 
2.34.1


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

* [PATCH v2 01/10] math: Add test to check if ceil raise inexact floating-point exception
  2024-04-03 12:11 [PATCH v2 00/10] Improve rounding to interger function for C23 Adhemerval Zanella
@ 2024-04-03 12:11 ` Adhemerval Zanella
  2024-04-03 12:54   ` H.J. Lu
  2024-04-03 12:11 ` [PATCH v2 02/10] math: Add test to check if floor " Adhemerval Zanella
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Adhemerval Zanella @ 2024-04-03 12:11 UTC (permalink / raw)
  To: libc-alpha; +Cc: H . J . Lu

It is not allowed anymore on ISO C23.
---
 math/Makefile             |  5 +++
 math/test-ceil-except-2.c | 67 ++++++++++++++++++++++++++++++
 math/test-ceil-except.c   | 85 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 157 insertions(+)
 create mode 100644 math/test-ceil-except-2.c
 create mode 100644 math/test-ceil-except.c

diff --git a/math/Makefile b/math/Makefile
index 121a709121..1017026d23 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -498,6 +498,8 @@ tests = \
   bug-nextafter \
   bug-nexttoward \
   bug-tgmath1 \
+  test-ceil-except \
+  test-ceil-except-2 \
   test-femode \
   test-femode-traps \
   test-fenv basic-test \
@@ -989,6 +991,9 @@ CFLAGS-test-fe-snans-always-signal.c += $(config-cflags-signaling-nans)
 
 CFLAGS-test-nan-const.c += -fno-builtin
 
+CFLAGS-test-ceil-except.c += -fno-builtin
+CFLAGS-test-ceil-except-2.c += -fno-builtin
+
 include ../Rules
 
 gen-all-calls = $(gen-libm-calls) $(gen-calls)
diff --git a/math/test-ceil-except-2.c b/math/test-ceil-except-2.c
new file mode 100644
index 0000000000..394a272d89
--- /dev/null
+++ b/math/test-ceil-except-2.c
@@ -0,0 +1,67 @@
+/* Test ceil functions do not disable exception traps.
+   Copyright (C) 2024 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 <fenv.h>
+#include <math.h>
+#include <stdio.h>
+
+#ifndef FE_INEXACT
+# define FE_INEXACT 0
+#endif
+
+#define TEST_FUNC(NAME, FLOAT, SUFFIX)					\
+static int								\
+NAME (void)								\
+{									\
+  int result = 0;							\
+  volatile FLOAT a, b __attribute__ ((unused));				\
+  a = 1.5;								\
+  /* ceil must work when traps on "inexact" are enabled.  */	\
+  b = ceil ## SUFFIX (a);						\
+  /* And it must have left those traps enabled.  */			\
+  if (fegetexcept () == FE_INEXACT)					\
+    puts ("PASS: " #FLOAT);						\
+  else									\
+    {									\
+      puts ("FAIL: " #FLOAT);						\
+      result = 1;							\
+    }									\
+  return result;							\
+}
+
+TEST_FUNC (float_test, float, f)
+TEST_FUNC (double_test, double, )
+TEST_FUNC (ldouble_test, long double, l)
+
+static int
+do_test (void)
+{
+  if (feenableexcept (FE_INEXACT) == -1)
+    {
+      puts ("enabling FE_INEXACT traps failed, cannot test");
+      return 77;
+    }
+  int result = float_test ();
+  feenableexcept (FE_INEXACT);
+  result |= double_test ();
+  feenableexcept (FE_INEXACT);
+  result |= ldouble_test ();
+  return result;
+}
+
+#include <support/test-driver.c>
diff --git a/math/test-ceil-except.c b/math/test-ceil-except.c
new file mode 100644
index 0000000000..f7627506f7
--- /dev/null
+++ b/math/test-ceil-except.c
@@ -0,0 +1,85 @@
+/* Test ceil functions do not clear exceptions.
+   Copyright (C) 2024 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 <fenv.h>
+#include <math.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#include <math-tests.h>
+
+#ifndef FE_INVALID
+# define FE_INVALID 0
+#endif
+
+static bool any_supported = false;
+
+#define TEST_FUNC(NAME, FLOAT, SUFFIX)					\
+static int								\
+NAME (void)								\
+{									\
+  int result = 0;							\
+  if (!EXCEPTION_TESTS (FLOAT))						\
+    return 0;								\
+  any_supported = true;							\
+  volatile FLOAT a, b __attribute__ ((unused));				\
+  a = 1.0;								\
+  /* ceil must not clear already-raised exceptions.  */		\
+  feraiseexcept (FE_ALL_EXCEPT);					\
+  b = ceil ## SUFFIX (a);						\
+  if (fetestexcept (FE_ALL_EXCEPT) == FE_ALL_EXCEPT)			\
+    puts ("PASS: " #FLOAT);						\
+  else									\
+    {									\
+      puts ("FAIL: " #FLOAT);						\
+      result = 1;							\
+    }									\
+  /* But it mustn't lose exceptions from sNaN arguments.  */		\
+  if (SNAN_TESTS (FLOAT))						\
+    {									\
+      static volatile FLOAT snan = __builtin_nans ## SUFFIX ("");	\
+      volatile FLOAT c __attribute__ ((unused));			\
+      feclearexcept (FE_ALL_EXCEPT);					\
+      c = ceil ## SUFFIX (snan);					\
+      if (fetestexcept (FE_INVALID) == FE_INVALID)			\
+	puts ("PASS: " #FLOAT " sNaN");					\
+      else								\
+	{								\
+	  puts ("FAIL: " #FLOAT " sNaN");				\
+	  result = 1;							\
+	}								\
+    }									\
+  return result;							\
+}
+
+TEST_FUNC (float_test, float, f)
+TEST_FUNC (double_test, double, )
+TEST_FUNC (ldouble_test, long double, l)
+
+static int
+do_test (void)
+{
+  int result = float_test ();
+  result |= double_test ();
+  result |= ldouble_test ();
+  if (!any_supported)
+    return 77;
+  return result;
+}
+
+#include <support/test-driver.c>
-- 
2.34.1


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

* [PATCH v2 02/10] math: Add test to check if floor raise inexact floating-point exception
  2024-04-03 12:11 [PATCH v2 00/10] Improve rounding to interger function for C23 Adhemerval Zanella
  2024-04-03 12:11 ` [PATCH v2 01/10] math: Add test to check if ceil raise inexact floating-point exception Adhemerval Zanella
@ 2024-04-03 12:11 ` Adhemerval Zanella
  2024-04-03 12:55   ` H.J. Lu
  2024-04-03 12:11 ` [PATCH v2 03/10] math: Add test to check if trunc " Adhemerval Zanella
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Adhemerval Zanella @ 2024-04-03 12:11 UTC (permalink / raw)
  To: libc-alpha; +Cc: H . J . Lu

It is not allowed anymore on ISO C23.
---
 math/Makefile              |  4 ++
 math/test-floor-except-2.c | 67 ++++++++++++++++++++++++++++++
 math/test-floor-except.c   | 85 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 156 insertions(+)
 create mode 100644 math/test-floor-except-2.c
 create mode 100644 math/test-floor-except.c

diff --git a/math/Makefile b/math/Makefile
index 1017026d23..8ab2582d69 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -512,6 +512,8 @@ tests = \
   test-fetestexceptflag \
   test-fexcept \
   test-fexcept-traps \
+  test-floor-except \
+  test-floor-except-2 \
   test-flt-eval-method \
   test-fp-ilogb-constants \
   test-fp-llogb-constants \
@@ -993,6 +995,8 @@ CFLAGS-test-nan-const.c += -fno-builtin
 
 CFLAGS-test-ceil-except.c += -fno-builtin
 CFLAGS-test-ceil-except-2.c += -fno-builtin
+CFLAGS-test-floor-except.c += -fno-builtin
+CFLAGS-test-floor-except-2.c += -fno-builtin
 
 include ../Rules
 
diff --git a/math/test-floor-except-2.c b/math/test-floor-except-2.c
new file mode 100644
index 0000000000..d99e835909
--- /dev/null
+++ b/math/test-floor-except-2.c
@@ -0,0 +1,67 @@
+/* Test floor functions do not disable exception traps.
+   Copyright (C) 2024 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 <fenv.h>
+#include <math.h>
+#include <stdio.h>
+
+#ifndef FE_INEXACT
+# define FE_INEXACT 0
+#endif
+
+#define TEST_FUNC(NAME, FLOAT, SUFFIX)					\
+static int								\
+NAME (void)								\
+{									\
+  int result = 0;							\
+  volatile FLOAT a, b __attribute__ ((unused));				\
+  a = 1.5;								\
+  /* floor must work when traps on "inexact" are enabled.  */	\
+  b = floor ## SUFFIX (a);						\
+  /* And it must have left those traps enabled.  */			\
+  if (fegetexcept () == FE_INEXACT)					\
+    puts ("PASS: " #FLOAT);						\
+  else									\
+    {									\
+      puts ("FAIL: " #FLOAT);						\
+      result = 1;							\
+    }									\
+  return result;							\
+}
+
+TEST_FUNC (float_test, float, f)
+TEST_FUNC (double_test, double, )
+TEST_FUNC (ldouble_test, long double, l)
+
+static int
+do_test (void)
+{
+  if (feenableexcept (FE_INEXACT) == -1)
+    {
+      puts ("enabling FE_INEXACT traps failed, cannot test");
+      return 77;
+    }
+  int result = float_test ();
+  feenableexcept (FE_INEXACT);
+  result |= double_test ();
+  feenableexcept (FE_INEXACT);
+  result |= ldouble_test ();
+  return result;
+}
+
+#include <support/test-driver.c>
diff --git a/math/test-floor-except.c b/math/test-floor-except.c
new file mode 100644
index 0000000000..a957c059e2
--- /dev/null
+++ b/math/test-floor-except.c
@@ -0,0 +1,85 @@
+/* Test floor functions do not clear exceptions.
+   Copyright (C) 2024 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 <fenv.h>
+#include <math.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#include <math-tests.h>
+
+#ifndef FE_INVALID
+# define FE_INVALID 0
+#endif
+
+static bool any_supported = false;
+
+#define TEST_FUNC(NAME, FLOAT, SUFFIX)					\
+static int								\
+NAME (void)								\
+{									\
+  int result = 0;							\
+  if (!EXCEPTION_TESTS (FLOAT))						\
+    return 0;								\
+  any_supported = true;							\
+  volatile FLOAT a, b __attribute__ ((unused));				\
+  a = 1.0;								\
+  /* floor must not clear already-raised exceptions.  */		\
+  feraiseexcept (FE_ALL_EXCEPT);					\
+  b = floor ## SUFFIX (a);						\
+  if (fetestexcept (FE_ALL_EXCEPT) == FE_ALL_EXCEPT)			\
+    puts ("PASS: " #FLOAT);						\
+  else									\
+    {									\
+      puts ("FAIL: " #FLOAT);						\
+      result = 1;							\
+    }									\
+  /* But it mustn't lose exceptions from sNaN arguments.  */		\
+  if (SNAN_TESTS (FLOAT))						\
+    {									\
+      static volatile FLOAT snan = __builtin_nans ## SUFFIX ("");	\
+      volatile FLOAT c __attribute__ ((unused));			\
+      feclearexcept (FE_ALL_EXCEPT);					\
+      c = floor ## SUFFIX (snan);					\
+      if (fetestexcept (FE_INVALID) == FE_INVALID)			\
+	puts ("PASS: " #FLOAT " sNaN");					\
+      else								\
+	{								\
+	  puts ("FAIL: " #FLOAT " sNaN");				\
+	  result = 1;							\
+	}								\
+    }									\
+  return result;							\
+}
+
+TEST_FUNC (float_test, float, f)
+TEST_FUNC (double_test, double, )
+TEST_FUNC (ldouble_test, long double, l)
+
+static int
+do_test (void)
+{
+  int result = float_test ();
+  result |= double_test ();
+  result |= ldouble_test ();
+  if (!any_supported)
+    return 77;
+  return result;
+}
+
+#include <support/test-driver.c>
-- 
2.34.1


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

* [PATCH v2 03/10] math: Add test to check if trunc raise inexact floating-point exception
  2024-04-03 12:11 [PATCH v2 00/10] Improve rounding to interger function for C23 Adhemerval Zanella
  2024-04-03 12:11 ` [PATCH v2 01/10] math: Add test to check if ceil raise inexact floating-point exception Adhemerval Zanella
  2024-04-03 12:11 ` [PATCH v2 02/10] math: Add test to check if floor " Adhemerval Zanella
@ 2024-04-03 12:11 ` Adhemerval Zanella
  2024-04-03 12:55   ` H.J. Lu
  2024-04-03 12:11 ` [PATCH v2 04/10] math: Add test to check if round " Adhemerval Zanella
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Adhemerval Zanella @ 2024-04-03 12:11 UTC (permalink / raw)
  To: libc-alpha; +Cc: H . J . Lu

It is not allowed anymore on ISO C23.
---
 math/Makefile              |  4 ++
 math/test-trunc-except-2.c | 67 ++++++++++++++++++++++++++++++
 math/test-trunc-except.c   | 85 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 156 insertions(+)
 create mode 100644 math/test-trunc-except-2.c
 create mode 100644 math/test-trunc-except.c

diff --git a/math/Makefile b/math/Makefile
index 8ab2582d69..32e3001ec6 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -541,6 +541,8 @@ tests = \
   test-tgmath-int \
   test-tgmath-ret \
   test-tgmath2 \
+  test-trunc-except \
+  test-trunc-except-2 \
   tst-CMPLX \
   tst-CMPLX2 \
   tst-definitions \
@@ -997,6 +999,8 @@ CFLAGS-test-ceil-except.c += -fno-builtin
 CFLAGS-test-ceil-except-2.c += -fno-builtin
 CFLAGS-test-floor-except.c += -fno-builtin
 CFLAGS-test-floor-except-2.c += -fno-builtin
+CFLAGS-test-trunc-except.c += -fno-builtin
+CFLAGS-test-trunc-except-2.c += -fno-builtin
 
 include ../Rules
 
diff --git a/math/test-trunc-except-2.c b/math/test-trunc-except-2.c
new file mode 100644
index 0000000000..8933c6ab41
--- /dev/null
+++ b/math/test-trunc-except-2.c
@@ -0,0 +1,67 @@
+/* Test trunc functions do not disable exception traps.
+   Copyright (C) 2024 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 <fenv.h>
+#include <math.h>
+#include <stdio.h>
+
+#ifndef FE_INEXACT
+# define FE_INEXACT 0
+#endif
+
+#define TEST_FUNC(NAME, FLOAT, SUFFIX)					\
+static int								\
+NAME (void)								\
+{									\
+  int result = 0;							\
+  volatile FLOAT a, b __attribute__ ((unused));				\
+  a = 1.5;								\
+  /* trunc must work when traps on "inexact" are enabled.  */	\
+  b = trunc ## SUFFIX (a);						\
+  /* And it must have left those traps enabled.  */			\
+  if (fegetexcept () == FE_INEXACT)					\
+    puts ("PASS: " #FLOAT);						\
+  else									\
+    {									\
+      puts ("FAIL: " #FLOAT);						\
+      result = 1;							\
+    }									\
+  return result;							\
+}
+
+TEST_FUNC (float_test, float, f)
+TEST_FUNC (double_test, double, )
+TEST_FUNC (ldouble_test, long double, l)
+
+static int
+do_test (void)
+{
+  if (feenableexcept (FE_INEXACT) == -1)
+    {
+      puts ("enabling FE_INEXACT traps failed, cannot test");
+      return 77;
+    }
+  int result = float_test ();
+  feenableexcept (FE_INEXACT);
+  result |= double_test ();
+  feenableexcept (FE_INEXACT);
+  result |= ldouble_test ();
+  return result;
+}
+
+#include <support/test-driver.c>
diff --git a/math/test-trunc-except.c b/math/test-trunc-except.c
new file mode 100644
index 0000000000..ff909d79ed
--- /dev/null
+++ b/math/test-trunc-except.c
@@ -0,0 +1,85 @@
+/* Test trunc functions do not clear exceptions.
+   Copyright (C) 2024 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 <fenv.h>
+#include <math.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#include <math-tests.h>
+
+#ifndef FE_INVALID
+# define FE_INVALID 0
+#endif
+
+static bool any_supported = false;
+
+#define TEST_FUNC(NAME, FLOAT, SUFFIX)					\
+static int								\
+NAME (void)								\
+{									\
+  int result = 0;							\
+  if (!EXCEPTION_TESTS (FLOAT))						\
+    return 0;								\
+  any_supported = true;							\
+  volatile FLOAT a, b __attribute__ ((unused));				\
+  a = 1.0;								\
+  /* trunc must not clear already-raised exceptions.  */		\
+  feraiseexcept (FE_ALL_EXCEPT);					\
+  b = trunc ## SUFFIX (a);						\
+  if (fetestexcept (FE_ALL_EXCEPT) == FE_ALL_EXCEPT)			\
+    puts ("PASS: " #FLOAT);						\
+  else									\
+    {									\
+      puts ("FAIL: " #FLOAT);						\
+      result = 1;							\
+    }									\
+  /* But it mustn't lose exceptions from sNaN arguments.  */		\
+  if (SNAN_TESTS (FLOAT))						\
+    {									\
+      static volatile FLOAT snan = __builtin_nans ## SUFFIX ("");	\
+      volatile FLOAT c __attribute__ ((unused));			\
+      feclearexcept (FE_ALL_EXCEPT);					\
+      c = trunc ## SUFFIX (snan);					\
+      if (fetestexcept (FE_INVALID) == FE_INVALID)			\
+	puts ("PASS: " #FLOAT " sNaN");					\
+      else								\
+	{								\
+	  puts ("FAIL: " #FLOAT " sNaN");				\
+	  result = 1;							\
+	}								\
+    }									\
+  return result;							\
+}
+
+TEST_FUNC (float_test, float, f)
+TEST_FUNC (double_test, double, )
+TEST_FUNC (ldouble_test, long double, l)
+
+static int
+do_test (void)
+{
+  int result = float_test ();
+  result |= double_test ();
+  result |= ldouble_test ();
+  if (!any_supported)
+    return 77;
+  return result;
+}
+
+#include <support/test-driver.c>
-- 
2.34.1


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

* [PATCH v2 04/10] math: Add test to check if round raise inexact floating-point exception
  2024-04-03 12:11 [PATCH v2 00/10] Improve rounding to interger function for C23 Adhemerval Zanella
                   ` (2 preceding siblings ...)
  2024-04-03 12:11 ` [PATCH v2 03/10] math: Add test to check if trunc " Adhemerval Zanella
@ 2024-04-03 12:11 ` Adhemerval Zanella
  2024-04-03 12:56   ` H.J. Lu
  2024-04-03 12:11 ` [PATCH v2 05/10] x86: Do not raise inexact exception on ceill Adhemerval Zanella
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Adhemerval Zanella @ 2024-04-03 12:11 UTC (permalink / raw)
  To: libc-alpha; +Cc: H . J . Lu

It is not allowed anymore on ISO C23.
---
 math/Makefile              |  4 ++
 math/test-round-except-2.c | 67 ++++++++++++++++++++++++++++++
 math/test-round-except.c   | 85 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 156 insertions(+)
 create mode 100644 math/test-round-except-2.c
 create mode 100644 math/test-round-except.c

diff --git a/math/Makefile b/math/Makefile
index 32e3001ec6..35a148a66c 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -530,6 +530,8 @@ tests = \
   test-nearbyint-except \
   test-nearbyint-except-2 \
   test-powl \
+  test-round-except \
+  test-round-except-2 \
   test-signgam-uchar \
   test-signgam-uchar-init \
   test-signgam-uint \
@@ -1001,6 +1003,8 @@ CFLAGS-test-floor-except.c += -fno-builtin
 CFLAGS-test-floor-except-2.c += -fno-builtin
 CFLAGS-test-trunc-except.c += -fno-builtin
 CFLAGS-test-trunc-except-2.c += -fno-builtin
+CFLAGS-test-round-except.c += -fno-builtin
+CFLAGS-test-round-except-2.c += -fno-builtin
 
 include ../Rules
 
diff --git a/math/test-round-except-2.c b/math/test-round-except-2.c
new file mode 100644
index 0000000000..5281b919b0
--- /dev/null
+++ b/math/test-round-except-2.c
@@ -0,0 +1,67 @@
+/* Test round functions do not disable exception traps.
+   Copyright (C) 2024 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 <fenv.h>
+#include <math.h>
+#include <stdio.h>
+
+#ifndef FE_INEXACT
+# define FE_INEXACT 0
+#endif
+
+#define TEST_FUNC(NAME, FLOAT, SUFFIX)					\
+static int								\
+NAME (void)								\
+{									\
+  int result = 0;							\
+  volatile FLOAT a, b __attribute__ ((unused));				\
+  a = 1.5;								\
+  /* round must work when traps on "inexact" are enabled.  */	\
+  b = round ## SUFFIX (a);						\
+  /* And it must have left those traps enabled.  */			\
+  if (fegetexcept () == FE_INEXACT)					\
+    puts ("PASS: " #FLOAT);						\
+  else									\
+    {									\
+      puts ("FAIL: " #FLOAT);						\
+      result = 1;							\
+    }									\
+  return result;							\
+}
+
+TEST_FUNC (float_test, float, f)
+TEST_FUNC (double_test, double, )
+TEST_FUNC (ldouble_test, long double, l)
+
+static int
+do_test (void)
+{
+  if (feenableexcept (FE_INEXACT) == -1)
+    {
+      puts ("enabling FE_INEXACT traps failed, cannot test");
+      return 77;
+    }
+  int result = float_test ();
+  feenableexcept (FE_INEXACT);
+  result |= double_test ();
+  feenableexcept (FE_INEXACT);
+  result |= ldouble_test ();
+  return result;
+}
+
+#include <support/test-driver.c>
diff --git a/math/test-round-except.c b/math/test-round-except.c
new file mode 100644
index 0000000000..c4515daf89
--- /dev/null
+++ b/math/test-round-except.c
@@ -0,0 +1,85 @@
+/* Test round functions do not clear exceptions.
+   Copyright (C) 2024 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 <fenv.h>
+#include <math.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#include <math-tests.h>
+
+#ifndef FE_INVALID
+# define FE_INVALID 0
+#endif
+
+static bool any_supported = false;
+
+#define TEST_FUNC(NAME, FLOAT, SUFFIX)					\
+static int								\
+NAME (void)								\
+{									\
+  int result = 0;							\
+  if (!EXCEPTION_TESTS (FLOAT))						\
+    return 0;								\
+  any_supported = true;							\
+  volatile FLOAT a, b __attribute__ ((unused));				\
+  a = 1.0;								\
+  /* round must not clear already-raised exceptions.  */		\
+  feraiseexcept (FE_ALL_EXCEPT);					\
+  b = round ## SUFFIX (a);						\
+  if (fetestexcept (FE_ALL_EXCEPT) == FE_ALL_EXCEPT)			\
+    puts ("PASS: " #FLOAT);						\
+  else									\
+    {									\
+      puts ("FAIL: " #FLOAT);						\
+      result = 1;							\
+    }									\
+  /* But it mustn't lose exceptions from sNaN arguments.  */		\
+  if (SNAN_TESTS (FLOAT))						\
+    {									\
+      static volatile FLOAT snan = __builtin_nans ## SUFFIX ("");	\
+      volatile FLOAT c __attribute__ ((unused));			\
+      feclearexcept (FE_ALL_EXCEPT);					\
+      c = round ## SUFFIX (snan);					\
+      if (fetestexcept (FE_INVALID) == FE_INVALID)			\
+	puts ("PASS: " #FLOAT " sNaN");					\
+      else								\
+	{								\
+	  puts ("FAIL: " #FLOAT " sNaN");				\
+	  result = 1;							\
+	}								\
+    }									\
+  return result;							\
+}
+
+TEST_FUNC (float_test, float, f)
+TEST_FUNC (double_test, double, )
+TEST_FUNC (ldouble_test, long double, l)
+
+static int
+do_test (void)
+{
+  int result = float_test ();
+  result |= double_test ();
+  result |= ldouble_test ();
+  if (!any_supported)
+    return 77;
+  return result;
+}
+
+#include <support/test-driver.c>
-- 
2.34.1


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

* [PATCH v2 05/10] x86: Do not raise inexact exception on ceill
  2024-04-03 12:11 [PATCH v2 00/10] Improve rounding to interger function for C23 Adhemerval Zanella
                   ` (3 preceding siblings ...)
  2024-04-03 12:11 ` [PATCH v2 04/10] math: Add test to check if round " Adhemerval Zanella
@ 2024-04-03 12:11 ` Adhemerval Zanella
  2024-04-03 13:04   ` H.J. Lu
  2024-04-03 12:11 ` [PATCH v2 06/10] x86: Do not raise inexact exception on floorl Adhemerval Zanella
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Adhemerval Zanella @ 2024-04-03 12:11 UTC (permalink / raw)
  To: libc-alpha; +Cc: H . J . Lu

It is not allowed anymore on ISO C23.

Checked on x86_64-linux-gnu and i686-linux-gnu.
---
 sysdeps/i386/fpu/s_ceill.S   | 39 ------------------------------------
 sysdeps/x86/fpu/s_ceill.c    | 38 +++++++++++++++++++++++++++++++++++
 sysdeps/x86_64/fpu/s_ceill.S | 34 -------------------------------
 3 files changed, 38 insertions(+), 73 deletions(-)
 delete mode 100644 sysdeps/i386/fpu/s_ceill.S
 create mode 100644 sysdeps/x86/fpu/s_ceill.c
 delete mode 100644 sysdeps/x86_64/fpu/s_ceill.S

diff --git a/sysdeps/i386/fpu/s_ceill.S b/sysdeps/i386/fpu/s_ceill.S
deleted file mode 100644
index a551fce7f9..0000000000
--- a/sysdeps/i386/fpu/s_ceill.S
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Public domain.
- */
-
-#include <libm-alias-ldouble.h>
-#include <machine/asm.h>
-
-RCSID("$NetBSD: $")
-
-ENTRY(__ceill)
-	fldt	4(%esp)
-	subl	$32,%esp
-	cfi_adjust_cfa_offset (32)
-
-	fnstenv	4(%esp)			/* store fpu environment */
-
-	/* We use here %edx although only the low 1 bits are defined.
-	   But none of the operations should care and they are faster
-	   than the 16 bit operations.  */
-	movl	$0x0800,%edx		/* round towards +oo */
-	orl	4(%esp),%edx
-	andl	$0xfbff,%edx
-	movl	%edx,(%esp)
-	fldcw	(%esp)			/* load modified control word */
-
-	frndint				/* round */
-
-	/* Preserve "invalid" exceptions from sNaN input.  */
-	fnstsw
-	andl	$0x1, %eax
-	orl	%eax, 8(%esp)
-
-	fldenv	4(%esp)			/* restore original environment */
-
-	addl	$32,%esp
-	cfi_adjust_cfa_offset (-32)
-	ret
-END (__ceill)
-libm_alias_ldouble (__ceil, ceil)
diff --git a/sysdeps/x86/fpu/s_ceill.c b/sysdeps/x86/fpu/s_ceill.c
new file mode 100644
index 0000000000..6ccc9d84d4
--- /dev/null
+++ b/sysdeps/x86/fpu/s_ceill.c
@@ -0,0 +1,38 @@
+/* Return smallest integral value not less than argument.  x86 version.
+   Copyright (C) 2024 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/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <fenv_private.h>
+#include <libm-alias-ldouble.h>
+
+long double
+__ceill (long double x)
+{
+  fenv_t fenv;
+  long double r;
+
+  libc_feholdexcept_setround_387 (&fenv, FE_UPWARD);
+  asm volatile ("frndint" : "=t" (r) : "0" (x));
+  /* Preserve "invalid" exceptions from sNaN input.  */
+  fenv.__status_word |= libc_fetestexcept_387 (FE_INVALID);
+  libc_fesetenv_387 (&fenv);
+
+  return r;
+}
+libm_alias_ldouble (__ceil, ceil)
diff --git a/sysdeps/x86_64/fpu/s_ceill.S b/sysdeps/x86_64/fpu/s_ceill.S
deleted file mode 100644
index 16dbecd56d..0000000000
--- a/sysdeps/x86_64/fpu/s_ceill.S
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Public domain.
- */
-
-#include <libm-alias-ldouble.h>
-#include <machine/asm.h>
-
-
-ENTRY(__ceill)
-	fldt	8(%rsp)
-
-	fnstenv	-28(%rsp)		/* store fpu environment */
-
-	/* We use here %edx although only the low 1 bits are defined.
-	   But none of the operations should care and they are faster
-	   than the 16 bit operations.  */
-	movl	$0x0800,%edx		/* round towards +oo */
-	orl	-28(%rsp),%edx
-	andl	$0xfbff,%edx
-	movl	%edx,-32(%rsp)
-	fldcw	-32(%rsp)		/* load modified control word */
-
-	frndint				/* round */
-
-	/* Preserve "invalid" exceptions from sNaN input.  */
-	fnstsw
-	andl	$0x1, %eax
-	orl	%eax, -24(%rsp)
-
-	fldenv	-28(%rsp)		/* restore original environment */
-
-	ret
-END (__ceill)
-libm_alias_ldouble (__ceil, ceil)
-- 
2.34.1


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

* [PATCH v2 06/10] x86: Do not raise inexact exception on floorl
  2024-04-03 12:11 [PATCH v2 00/10] Improve rounding to interger function for C23 Adhemerval Zanella
                   ` (4 preceding siblings ...)
  2024-04-03 12:11 ` [PATCH v2 05/10] x86: Do not raise inexact exception on ceill Adhemerval Zanella
@ 2024-04-03 12:11 ` Adhemerval Zanella
  2024-04-03 12:11 ` [PATCH v2 07/10] x86: Do not raise inexact exception on truncl Adhemerval Zanella
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Adhemerval Zanella @ 2024-04-03 12:11 UTC (permalink / raw)
  To: libc-alpha; +Cc: H . J . Lu

It is not allowed anymore on ISO C23.

Checked on x86_64-linux-gnu and i686-linux-gnu.
---
 sysdeps/i386/fpu/s_floorl.S   | 39 -----------------------------------
 sysdeps/x86/fpu/s_floorl.c    | 38 ++++++++++++++++++++++++++++++++++
 sysdeps/x86_64/fpu/s_floorl.S | 33 -----------------------------
 3 files changed, 38 insertions(+), 72 deletions(-)
 delete mode 100644 sysdeps/i386/fpu/s_floorl.S
 create mode 100644 sysdeps/x86/fpu/s_floorl.c
 delete mode 100644 sysdeps/x86_64/fpu/s_floorl.S

diff --git a/sysdeps/i386/fpu/s_floorl.S b/sysdeps/i386/fpu/s_floorl.S
deleted file mode 100644
index 3ec28b477b..0000000000
--- a/sysdeps/i386/fpu/s_floorl.S
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Public domain.
- */
-
-#include <libm-alias-ldouble.h>
-#include <machine/asm.h>
-
-RCSID("$NetBSD: $")
-
-ENTRY(__floorl)
-	fldt	4(%esp)
-	subl	$32,%esp
-	cfi_adjust_cfa_offset (32)
-
-	fnstenv	4(%esp)			/* store fpu environment */
-
-	/* We use here %edx although only the low 1 bits are defined.
-	   But none of the operations should care and they are faster
-	   than the 16 bit operations.  */
-	movl	$0x400,%edx		/* round towards -oo */
-	orl	4(%esp),%edx
-	andl	$0xf7ff,%edx
-	movl	%edx,(%esp)
-	fldcw	(%esp)			/* load modified control word */
-
-	frndint				/* round */
-
-	/* Preserve "invalid" exceptions from sNaN input.  */
-	fnstsw
-	andl	$0x1, %eax
-	orl	%eax, 8(%esp)
-
-	fldenv	4(%esp)			/* restore original environment */
-
-	addl	$32,%esp
-	cfi_adjust_cfa_offset (-32)
-	ret
-END (__floorl)
-libm_alias_ldouble (__floor, floor)
diff --git a/sysdeps/x86/fpu/s_floorl.c b/sysdeps/x86/fpu/s_floorl.c
new file mode 100644
index 0000000000..3eca033f46
--- /dev/null
+++ b/sysdeps/x86/fpu/s_floorl.c
@@ -0,0 +1,38 @@
+/* Return largest integral value not less than argument.  x86 version.
+   Copyright (C) 2024 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/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <fenv_private.h>
+#include <libm-alias-ldouble.h>
+
+long double
+__floorl (long double x)
+{
+  fenv_t fenv;
+  long double r;
+
+  libc_feholdexcept_setround_387 (&fenv, FE_DOWNWARD);
+  asm volatile ("frndint" : "=t" (r) : "0" (x));
+  /* Preserve "invalid" exceptions from sNaN input.  */
+  fenv.__status_word |= libc_fetestexcept_387 (FE_INVALID);
+  libc_fesetenv_387 (&fenv);
+
+  return r;
+}
+libm_alias_ldouble (__floor, floor)
diff --git a/sysdeps/x86_64/fpu/s_floorl.S b/sysdeps/x86_64/fpu/s_floorl.S
deleted file mode 100644
index b74d1a4d6b..0000000000
--- a/sysdeps/x86_64/fpu/s_floorl.S
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Public domain.
- */
-
-#include <libm-alias-ldouble.h>
-#include <machine/asm.h>
-
-ENTRY(__floorl)
-	fldt	8(%rsp)
-
-	fnstenv	-28(%rsp)		/* store fpu environment */
-
-	/* We use here %edx although only the low 1 bits are defined.
-	   But none of the operations should care and they are faster
-	   than the 16 bit operations.  */
-	movl	$0x400,%edx		/* round towards -oo */
-	orl	-28(%rsp),%edx
-	andl	$0xf7ff,%edx
-	movl	%edx,-32(%rsp)
-	fldcw	-32(%rsp)		/* load modified control word */
-
-	frndint				/* round */
-
-	/* Preserve "invalid" exceptions from sNaN input.  */
-	fnstsw
-	andl	$0x1, %eax
-	orl	%eax, -24(%rsp)
-
-	fldenv	-28(%rsp)		/* restore original environment */
-
-	ret
-END (__floorl)
-libm_alias_ldouble (__floor, floor)
-- 
2.34.1


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

* [PATCH v2 07/10] x86: Do not raise inexact exception on truncl
  2024-04-03 12:11 [PATCH v2 00/10] Improve rounding to interger function for C23 Adhemerval Zanella
                   ` (5 preceding siblings ...)
  2024-04-03 12:11 ` [PATCH v2 06/10] x86: Do not raise inexact exception on floorl Adhemerval Zanella
@ 2024-04-03 12:11 ` Adhemerval Zanella
  2024-04-03 12:11 ` [PATCH v2 08/10] x86: Do not raise inexact exception on floor/floorf Adhemerval Zanella
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Adhemerval Zanella @ 2024-04-03 12:11 UTC (permalink / raw)
  To: libc-alpha; +Cc: H . J . Lu

It is not allowed anymore on ISO C23.

Checked on x86_64-linux-gnu and i686-linux-gnu.
---
 .../fpu/s_truncl.S => x86/fpu/s_truncl.c}     | 40 +++++++++----------
 sysdeps/x86_64/fpu/s_truncl.S                 | 36 -----------------
 2 files changed, 19 insertions(+), 57 deletions(-)
 rename sysdeps/{i386/fpu/s_truncl.S => x86/fpu/s_truncl.c} (61%)
 delete mode 100644 sysdeps/x86_64/fpu/s_truncl.S

diff --git a/sysdeps/i386/fpu/s_truncl.S b/sysdeps/x86/fpu/s_truncl.c
similarity index 61%
rename from sysdeps/i386/fpu/s_truncl.S
rename to sysdeps/x86/fpu/s_truncl.c
index dfd0ca4a57..59614cd006 100644
--- a/sysdeps/i386/fpu/s_truncl.S
+++ b/sysdeps/x86/fpu/s_truncl.c
@@ -1,5 +1,5 @@
-/* Truncate long double value.
-   Copyright (C) 1997-2024 Free Software Foundation, Inc.
+/* Round to integer, toward zero.  x86 version.
+   Copyright (C) 2024 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
@@ -16,25 +16,23 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <fenv_private.h>
 #include <libm-alias-ldouble.h>
-#include <machine/asm.h>
 
-ENTRY(__truncl)
-	fldt	4(%esp)
-	subl	$32, %esp
-	cfi_adjust_cfa_offset (32)
-	fnstenv	4(%esp)
-	movl	$0xc00, %edx
-	orl	4(%esp), %edx
-	movl	%edx, (%esp)
-	fldcw	(%esp)
-	frndint
-	fnstsw
-	andl	$0x1, %eax
-	orl	%eax, 8(%esp)
-	fldenv	4(%esp)
-	addl	$32, %esp
-	cfi_adjust_cfa_offset (-32)
-	ret
-END(__truncl)
+long double
+__truncl (long double x)
+{
+  fenv_t fenv;
+  long double r;
+
+  libc_feholdexcept_setround_387 (&fenv, FE_TOWARDZERO);
+  asm volatile ("frndint" : "=t" (r) : "0" (x));
+  /* Preserve "invalid" exceptions from sNaN input.  */
+  fenv.__status_word |= libc_fetestexcept_387 (FE_INVALID);
+  libc_fesetenv_387 (&fenv);
+
+  return r;
+}
 libm_alias_ldouble (__trunc, trunc)
diff --git a/sysdeps/x86_64/fpu/s_truncl.S b/sysdeps/x86_64/fpu/s_truncl.S
deleted file mode 100644
index e3d64a84e8..0000000000
--- a/sysdeps/x86_64/fpu/s_truncl.S
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Truncate long double value.
-   Copyright (C) 1997-2024 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 <libm-alias-ldouble.h>
-#include <machine/asm.h>
-
-ENTRY(__truncl)
-	fldt	8(%rsp)
-	fnstenv	-28(%rsp)
-	movl	$0xc00, %edx
-	orl	-28(%rsp), %edx
-	movl	%edx, -32(%rsp)
-	fldcw	-32(%rsp)
-	frndint
-	fnstsw
-	andl	$0x1, %eax
-	orl	%eax, -24(%rsp)
-	fldenv	-28(%rsp)
-	ret
-END(__truncl)
-libm_alias_ldouble (__trunc, trunc)
-- 
2.34.1


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

* [PATCH v2 08/10] x86: Do not raise inexact exception on floor/floorf
  2024-04-03 12:11 [PATCH v2 00/10] Improve rounding to interger function for C23 Adhemerval Zanella
                   ` (6 preceding siblings ...)
  2024-04-03 12:11 ` [PATCH v2 07/10] x86: Do not raise inexact exception on truncl Adhemerval Zanella
@ 2024-04-03 12:11 ` Adhemerval Zanella
  2024-04-03 12:11 ` [PATCH v2 09/10] i386: Do not raise inexact exception on ceil/ceilf Adhemerval Zanella
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Adhemerval Zanella @ 2024-04-03 12:11 UTC (permalink / raw)
  To: libc-alpha; +Cc: H . J . Lu

It is not allowed anymore on ISO C23.

Checked on x86_64-linux-gnu and i686-linux-gnu.
---
 sysdeps/i386/fpu/s_floor.S  | 34 ---------------------------------
 sysdeps/i386/fpu/s_floor.c  | 38 +++++++++++++++++++++++++++++++++++++
 sysdeps/i386/fpu/s_floorf.S | 34 ---------------------------------
 sysdeps/i386/fpu/s_floorf.c | 38 +++++++++++++++++++++++++++++++++++++
 4 files changed, 76 insertions(+), 68 deletions(-)
 delete mode 100644 sysdeps/i386/fpu/s_floor.S
 create mode 100644 sysdeps/i386/fpu/s_floor.c
 delete mode 100644 sysdeps/i386/fpu/s_floorf.S
 create mode 100644 sysdeps/i386/fpu/s_floorf.c

diff --git a/sysdeps/i386/fpu/s_floor.S b/sysdeps/i386/fpu/s_floor.S
deleted file mode 100644
index 7143fdcc9a..0000000000
--- a/sysdeps/i386/fpu/s_floor.S
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Public domain.
- */
-
-#include <machine/asm.h>
-#include <libm-alias-double.h>
-
-RCSID("$NetBSD: s_floor.S,v 1.4 1995/05/09 00:01:59 jtc Exp $")
-
-ENTRY(__floor)
-	fldl	4(%esp)
-	subl	$32,%esp
-	cfi_adjust_cfa_offset (32)
-
-	fnstenv	4(%esp)			/* store fpu environment */
-
-	/* We use here %edx although only the low 1 bits are defined.
-	   But none of the operations should care and they are faster
-	   than the 16 bit operations.  */
-	movl	$0x400,%edx		/* round towards -oo */
-	orl	4(%esp),%edx
-	andl	$0xf7ff,%edx
-	movl	%edx,(%esp)
-	fldcw	(%esp)			/* load modified control word */
-
-	frndint				/* round */
-
-	fldenv	4(%esp)			/* restore original environment */
-
-	addl	$32,%esp
-	cfi_adjust_cfa_offset (-32)
-	ret
-END (__floor)
-libm_alias_double (__floor, floor)
diff --git a/sysdeps/i386/fpu/s_floor.c b/sysdeps/i386/fpu/s_floor.c
new file mode 100644
index 0000000000..8e763327ad
--- /dev/null
+++ b/sysdeps/i386/fpu/s_floor.c
@@ -0,0 +1,38 @@
+/* Return largest integral value not less than argument.  i386 version.
+   Copyright (C) 2024 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/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <fenv_private.h>
+#include <libm-alias-double.h>
+
+double
+__floor (double x)
+{
+  fenv_t fenv;
+  double r;
+
+  libc_feholdexcept_setround_387 (&fenv, FE_DOWNWARD);
+  asm volatile ("frndint" : "=t" (r) : "0" (x));
+  /* Preserve "invalid" exceptions from sNaN input.  */
+  fenv.__status_word |= libc_fetestexcept_387 (FE_INVALID);
+  libc_fesetenv_387 (&fenv);
+
+  return r;
+}
+libm_alias_double (__floor, floor)
diff --git a/sysdeps/i386/fpu/s_floorf.S b/sysdeps/i386/fpu/s_floorf.S
deleted file mode 100644
index 8fad9c0698..0000000000
--- a/sysdeps/i386/fpu/s_floorf.S
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Public domain.
- */
-
-#include <machine/asm.h>
-#include <libm-alias-float.h>
-
-RCSID("$NetBSD: s_floorf.S,v 1.3 1995/05/09 00:04:32 jtc Exp $")
-
-ENTRY(__floorf)
-	flds	4(%esp)
-	subl	$32,%esp
-	cfi_adjust_cfa_offset (32)
-
-	fnstenv	4(%esp)			/* store fpu environment */
-
-	/* We use here %edx although only the low 1 bits are defined.
-	   But none of the operations should care and they are faster
-	   than the 16 bit operations.  */
-	movl	$0x400,%edx		/* round towards -oo */
-	orl	4(%esp),%edx
-	andl	$0xf7ff,%edx
-	movl	%edx,(%esp)
-	fldcw	(%esp)			/* load modified control word */
-
-	frndint				/* round */
-
-	fldenv	4(%esp)			/* restore original environment */
-
-	addl	$32,%esp
-	cfi_adjust_cfa_offset (-32)
-	ret
-END (__floorf)
-libm_alias_float (__floor, floor)
diff --git a/sysdeps/i386/fpu/s_floorf.c b/sysdeps/i386/fpu/s_floorf.c
new file mode 100644
index 0000000000..e5ff58c8c6
--- /dev/null
+++ b/sysdeps/i386/fpu/s_floorf.c
@@ -0,0 +1,38 @@
+/* Return largest integral value not less than argument.  i386 version.
+   Copyright (C) 2024 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/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <fenv_private.h>
+#include <libm-alias-float.h>
+
+float
+__floorf (float x)
+{
+  fenv_t fenv;
+  float r;
+
+  libc_feholdexcept_setround_387 (&fenv, FE_DOWNWARD);
+  asm volatile ("frndint" : "=t" (r) : "0" (x));
+  /* Preserve "invalid" exceptions from sNaN input.  */
+  fenv.__status_word |= libc_fetestexcept_387 (FE_INVALID);
+  libc_fesetenv_387 (&fenv);
+
+  return r;
+}
+libm_alias_float (__floor, floor)
-- 
2.34.1


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

* [PATCH v2 09/10] i386: Do not raise inexact exception on ceil/ceilf
  2024-04-03 12:11 [PATCH v2 00/10] Improve rounding to interger function for C23 Adhemerval Zanella
                   ` (7 preceding siblings ...)
  2024-04-03 12:11 ` [PATCH v2 08/10] x86: Do not raise inexact exception on floor/floorf Adhemerval Zanella
@ 2024-04-03 12:11 ` Adhemerval Zanella
  2024-04-03 12:11 ` [PATCH v2 10/10] i386: Do not raise inexact exception on trunc/truncf Adhemerval Zanella
  2024-04-03 15:03 ` [PATCH v2 00/10] Improve rounding to interger function for C23 Joseph Myers
  10 siblings, 0 replies; 21+ messages in thread
From: Adhemerval Zanella @ 2024-04-03 12:11 UTC (permalink / raw)
  To: libc-alpha; +Cc: H . J . Lu

It is not allowed anymore on ISO C23.

Checked on x86_64-linux-gnu and i686-linux-gnu.
---
 sysdeps/i386/fpu/s_ceil.S  | 34 ----------------------------------
 sysdeps/i386/fpu/s_ceil.c  | 38 ++++++++++++++++++++++++++++++++++++++
 sysdeps/i386/fpu/s_ceilf.S | 34 ----------------------------------
 sysdeps/i386/fpu/s_ceilf.c | 38 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 76 insertions(+), 68 deletions(-)
 delete mode 100644 sysdeps/i386/fpu/s_ceil.S
 create mode 100644 sysdeps/i386/fpu/s_ceil.c
 delete mode 100644 sysdeps/i386/fpu/s_ceilf.S
 create mode 100644 sysdeps/i386/fpu/s_ceilf.c

diff --git a/sysdeps/i386/fpu/s_ceil.S b/sysdeps/i386/fpu/s_ceil.S
deleted file mode 100644
index 99984f9b8d..0000000000
--- a/sysdeps/i386/fpu/s_ceil.S
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Public domain.
- */
-
-#include <machine/asm.h>
-#include <libm-alias-double.h>
-
-RCSID("$NetBSD: s_ceil.S,v 1.4 1995/05/08 23:52:13 jtc Exp $")
-
-ENTRY(__ceil)
-	fldl	4(%esp)
-	subl	$32,%esp
-	cfi_adjust_cfa_offset (32)
-
-	fnstenv	4(%esp)			/* store fpu environment */
-
-	/* We use here %edx although only the low 1 bits are defined.
-	   But none of the operations should care and they are faster
-	   than the 16 bit operations.  */
-	movl	$0x0800,%edx		/* round towards +oo */
-	orl	4(%esp),%edx
-	andl	$0xfbff,%edx
-	movl	%edx,(%esp)
-	fldcw	(%esp)			/* load modified control word */
-
-	frndint				/* round */
-
-	fldenv	4(%esp)			/* restore original environment */
-
-	addl	$32,%esp
-	cfi_adjust_cfa_offset (-32)
-	ret
-END (__ceil)
-libm_alias_double (__ceil, ceil)
diff --git a/sysdeps/i386/fpu/s_ceil.c b/sysdeps/i386/fpu/s_ceil.c
new file mode 100644
index 0000000000..1ab3d357ba
--- /dev/null
+++ b/sysdeps/i386/fpu/s_ceil.c
@@ -0,0 +1,38 @@
+/* Return smallest integral value not less than argument.  i386 version.
+   Copyright (C) 2024 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/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <fenv_private.h>
+#include <libm-alias-double.h>
+
+double
+__ceil (double x)
+{
+  fenv_t fenv;
+  double r;
+
+  libc_feholdexcept_setround_387 (&fenv, FE_UPWARD);
+  asm volatile ("frndint" : "=t" (r) : "0" (x));
+  /* Preserve "invalid" exceptions from sNaN input.  */
+  fenv.__status_word |= libc_fetestexcept_387 (FE_INVALID);
+  libc_fesetenv_387 (&fenv);
+
+  return r;
+}
+libm_alias_double (__ceil, ceil)
diff --git a/sysdeps/i386/fpu/s_ceilf.S b/sysdeps/i386/fpu/s_ceilf.S
deleted file mode 100644
index 03e8e22609..0000000000
--- a/sysdeps/i386/fpu/s_ceilf.S
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Public domain.
- */
-
-#include <machine/asm.h>
-#include <libm-alias-float.h>
-
-RCSID("$NetBSD: s_ceilf.S,v 1.3 1995/05/08 23:52:44 jtc Exp $")
-
-ENTRY(__ceilf)
-	flds	4(%esp)
-	subl	$32,%esp
-	cfi_adjust_cfa_offset (32)
-
-	fnstenv	4(%esp)			/* store fpu environment */
-
-	/* We use here %edx although only the low 1 bits are defined.
-	   But none of the operations should care and they are faster
-	   than the 16 bit operations.  */
-	movl	$0x0800,%edx		/* round towards +oo */
-	orl	4(%esp),%edx
-	andl	$0xfbff,%edx
-	movl	%edx,(%esp)
-	fldcw	(%esp)			/* load modified control word */
-
-	frndint				/* round */
-
-	fldenv	4(%esp)			/* restore original environment */
-
-	addl	$32,%esp
-	cfi_adjust_cfa_offset (-32)
-	ret
-END (__ceilf)
-libm_alias_float (__ceil, ceil)
diff --git a/sysdeps/i386/fpu/s_ceilf.c b/sysdeps/i386/fpu/s_ceilf.c
new file mode 100644
index 0000000000..3de0a962f3
--- /dev/null
+++ b/sysdeps/i386/fpu/s_ceilf.c
@@ -0,0 +1,38 @@
+/* Return largest integral value not less than argument.  i386 version.
+   Copyright (C) 2024 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/>.  */
+
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <fenv_private.h>
+#include <libm-alias-float.h>
+
+float
+__ceilf (float x)
+{
+  fenv_t fenv;
+  float r;
+
+  libc_feholdexcept_setround_387 (&fenv, FE_UPWARD);
+  asm volatile ("frndint" : "=t" (r) : "0" (x));
+  /* Preserve "invalid" exceptions from sNaN input.  */
+  fenv.__status_word |= libc_fetestexcept_387 (FE_INVALID);
+  libc_fesetenv_387 (&fenv);
+
+  return r;
+}
+libm_alias_float (__ceil, ceil)
-- 
2.34.1


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

* [PATCH v2 10/10] i386: Do not raise inexact exception on trunc/truncf
  2024-04-03 12:11 [PATCH v2 00/10] Improve rounding to interger function for C23 Adhemerval Zanella
                   ` (8 preceding siblings ...)
  2024-04-03 12:11 ` [PATCH v2 09/10] i386: Do not raise inexact exception on ceil/ceilf Adhemerval Zanella
@ 2024-04-03 12:11 ` Adhemerval Zanella
  2024-04-03 15:03 ` [PATCH v2 00/10] Improve rounding to interger function for C23 Joseph Myers
  10 siblings, 0 replies; 21+ messages in thread
From: Adhemerval Zanella @ 2024-04-03 12:11 UTC (permalink / raw)
  To: libc-alpha; +Cc: H . J . Lu

It is not allowed anymore on ISO C23.

Checked on x86_64-linux-gnu and i686-linux-gnu.
---
 sysdeps/i386/fpu/{s_trunc.S => s_trunc.c}   | 37 +++++++++++----------
 sysdeps/i386/fpu/{s_truncf.S => s_truncf.c} | 37 +++++++++++----------
 2 files changed, 38 insertions(+), 36 deletions(-)
 rename sysdeps/i386/fpu/{s_trunc.S => s_trunc.c} (61%)
 rename sysdeps/i386/fpu/{s_truncf.S => s_truncf.c} (61%)

diff --git a/sysdeps/i386/fpu/s_trunc.S b/sysdeps/i386/fpu/s_trunc.c
similarity index 61%
rename from sysdeps/i386/fpu/s_trunc.S
rename to sysdeps/i386/fpu/s_trunc.c
index 40e45c9f9c..5880964499 100644
--- a/sysdeps/i386/fpu/s_trunc.S
+++ b/sysdeps/i386/fpu/s_trunc.c
@@ -1,5 +1,5 @@
-/* Truncate double value.
-   Copyright (C) 1997-2024 Free Software Foundation, Inc.
+/* Round to integer, toward zero.  i386 version.
+   Copyright (C) 2024 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
@@ -16,22 +16,23 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <machine/asm.h>
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <fenv_private.h>
 #include <libm-alias-double.h>
 
-ENTRY(__trunc)
-	fldl	4(%esp)
-	subl	$32, %esp
-	cfi_adjust_cfa_offset (32)
-	fnstenv	4(%esp)
-	movl	$0xc00, %edx
-	orl	4(%esp), %edx
-	movl	%edx, (%esp)
-	fldcw	(%esp)
-	frndint
-	fldenv	4(%esp)
-	addl	$32, %esp
-	cfi_adjust_cfa_offset (-32)
-	ret
-END(__trunc)
+double
+__trunc (double x)
+{
+  fenv_t fenv;
+  double r;
+
+  libc_feholdexcept_setround_387 (&fenv, FE_TOWARDZERO);
+  asm volatile ("frndint" : "=t" (r) : "0" (x));
+  /* Preserve "invalid" exceptions from sNaN input.  */
+  fenv.__status_word |= libc_fetestexcept_387 (FE_INVALID);
+  libc_fesetenv_387 (&fenv);
+
+  return r;
+}
 libm_alias_double (__trunc, trunc)
diff --git a/sysdeps/i386/fpu/s_truncf.S b/sysdeps/i386/fpu/s_truncf.c
similarity index 61%
rename from sysdeps/i386/fpu/s_truncf.S
rename to sysdeps/i386/fpu/s_truncf.c
index 0b26e09d61..037099024f 100644
--- a/sysdeps/i386/fpu/s_truncf.S
+++ b/sysdeps/i386/fpu/s_truncf.c
@@ -1,5 +1,5 @@
-/* Truncate float value.
-   Copyright (C) 1997-2024 Free Software Foundation, Inc.
+/* Round to integer, toward zero.  i386 version.
+   Copyright (C) 2024 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
@@ -16,22 +16,23 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <machine/asm.h>
+#define NO_MATH_REDIRECT
+#include <math.h>
+#include <fenv_private.h>
 #include <libm-alias-float.h>
 
-ENTRY(__truncf)
-	flds	4(%esp)
-	subl	$32, %esp
-	cfi_adjust_cfa_offset (32)
-	fnstenv	4(%esp)
-	movl	$0xc00, %edx
-	orl	4(%esp), %edx
-	movl	%edx, (%esp)
-	fldcw	(%esp)
-	frndint
-	fldenv	4(%esp)
-	addl	$32, %esp
-	cfi_adjust_cfa_offset (-32)
-	ret
-END(__truncf)
+float
+__truncf (float x)
+{
+  fenv_t fenv;
+  float r;
+
+  libc_feholdexcept_setround_387 (&fenv, FE_TOWARDZERO);
+  asm volatile ("frndint" : "=t" (r) : "0" (x));
+  /* Preserve "invalid" exceptions from sNaN input.  */
+  fenv.__status_word |= libc_fetestexcept_387 (FE_INVALID);
+  libc_fesetenv_387 (&fenv);
+
+  return r;
+}
 libm_alias_float (__trunc, trunc)
-- 
2.34.1


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

* Re: [PATCH v2 01/10] math: Add test to check if ceil raise inexact floating-point exception
  2024-04-03 12:11 ` [PATCH v2 01/10] math: Add test to check if ceil raise inexact floating-point exception Adhemerval Zanella
@ 2024-04-03 12:54   ` H.J. Lu
  0 siblings, 0 replies; 21+ messages in thread
From: H.J. Lu @ 2024-04-03 12:54 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

On Wed, Apr 3, 2024 at 5:11 AM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
> It is not allowed anymore on ISO C23.
> ---
>  math/Makefile             |  5 +++
>  math/test-ceil-except-2.c | 67 ++++++++++++++++++++++++++++++
>  math/test-ceil-except.c   | 85 +++++++++++++++++++++++++++++++++++++++
>  3 files changed, 157 insertions(+)
>  create mode 100644 math/test-ceil-except-2.c
>  create mode 100644 math/test-ceil-except.c
>
> diff --git a/math/Makefile b/math/Makefile
> index 121a709121..1017026d23 100644
> --- a/math/Makefile
> +++ b/math/Makefile
> @@ -498,6 +498,8 @@ tests = \
>    bug-nextafter \
>    bug-nexttoward \
>    bug-tgmath1 \
> +  test-ceil-except \
> +  test-ceil-except-2 \
>    test-femode \
>    test-femode-traps \
>    test-fenv basic-test \
> @@ -989,6 +991,9 @@ CFLAGS-test-fe-snans-always-signal.c += $(config-cflags-signaling-nans)
>
>  CFLAGS-test-nan-const.c += -fno-builtin
>
> +CFLAGS-test-ceil-except.c += -fno-builtin
> +CFLAGS-test-ceil-except-2.c += -fno-builtin
> +
>  include ../Rules
>
>  gen-all-calls = $(gen-libm-calls) $(gen-calls)
> diff --git a/math/test-ceil-except-2.c b/math/test-ceil-except-2.c
> new file mode 100644
> index 0000000000..394a272d89
> --- /dev/null
> +++ b/math/test-ceil-except-2.c
> @@ -0,0 +1,67 @@
> +/* Test ceil functions do not disable exception traps.
> +   Copyright (C) 2024 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 <fenv.h>
> +#include <math.h>
> +#include <stdio.h>
> +
> +#ifndef FE_INEXACT
> +# define FE_INEXACT 0
> +#endif
> +
> +#define TEST_FUNC(NAME, FLOAT, SUFFIX)                                 \
> +static int                                                             \
> +NAME (void)                                                            \
> +{                                                                      \
> +  int result = 0;                                                      \
> +  volatile FLOAT a, b __attribute__ ((unused));                                \
> +  a = 1.5;                                                             \
> +  /* ceil must work when traps on "inexact" are enabled.  */   \
> +  b = ceil ## SUFFIX (a);                                              \
> +  /* And it must have left those traps enabled.  */                    \
> +  if (fegetexcept () == FE_INEXACT)                                    \
> +    puts ("PASS: " #FLOAT);                                            \
> +  else                                                                 \
> +    {                                                                  \
> +      puts ("FAIL: " #FLOAT);                                          \
> +      result = 1;                                                      \
> +    }                                                                  \
> +  return result;                                                       \
> +}
> +
> +TEST_FUNC (float_test, float, f)
> +TEST_FUNC (double_test, double, )
> +TEST_FUNC (ldouble_test, long double, l)
> +
> +static int
> +do_test (void)
> +{
> +  if (feenableexcept (FE_INEXACT) == -1)
> +    {
> +      puts ("enabling FE_INEXACT traps failed, cannot test");
> +      return 77;
> +    }
> +  int result = float_test ();
> +  feenableexcept (FE_INEXACT);
> +  result |= double_test ();
> +  feenableexcept (FE_INEXACT);
> +  result |= ldouble_test ();
> +  return result;
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/math/test-ceil-except.c b/math/test-ceil-except.c
> new file mode 100644
> index 0000000000..f7627506f7
> --- /dev/null
> +++ b/math/test-ceil-except.c
> @@ -0,0 +1,85 @@
> +/* Test ceil functions do not clear exceptions.
> +   Copyright (C) 2024 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 <fenv.h>
> +#include <math.h>
> +#include <stdbool.h>
> +#include <stdio.h>
> +
> +#include <math-tests.h>
> +
> +#ifndef FE_INVALID
> +# define FE_INVALID 0
> +#endif
> +
> +static bool any_supported = false;
> +
> +#define TEST_FUNC(NAME, FLOAT, SUFFIX)                                 \
> +static int                                                             \
> +NAME (void)                                                            \
> +{                                                                      \
> +  int result = 0;                                                      \
> +  if (!EXCEPTION_TESTS (FLOAT))                                                \
> +    return 0;                                                          \
> +  any_supported = true;                                                        \
> +  volatile FLOAT a, b __attribute__ ((unused));                                \
> +  a = 1.0;                                                             \
> +  /* ceil must not clear already-raised exceptions.  */                \
> +  feraiseexcept (FE_ALL_EXCEPT);                                       \
> +  b = ceil ## SUFFIX (a);                                              \
> +  if (fetestexcept (FE_ALL_EXCEPT) == FE_ALL_EXCEPT)                   \
> +    puts ("PASS: " #FLOAT);                                            \
> +  else                                                                 \
> +    {                                                                  \
> +      puts ("FAIL: " #FLOAT);                                          \
> +      result = 1;                                                      \
> +    }                                                                  \
> +  /* But it mustn't lose exceptions from sNaN arguments.  */           \
> +  if (SNAN_TESTS (FLOAT))                                              \
> +    {                                                                  \
> +      static volatile FLOAT snan = __builtin_nans ## SUFFIX ("");      \
> +      volatile FLOAT c __attribute__ ((unused));                       \
> +      feclearexcept (FE_ALL_EXCEPT);                                   \
> +      c = ceil ## SUFFIX (snan);                                       \
> +      if (fetestexcept (FE_INVALID) == FE_INVALID)                     \
> +       puts ("PASS: " #FLOAT " sNaN");                                 \
> +      else                                                             \
> +       {                                                               \
> +         puts ("FAIL: " #FLOAT " sNaN");                               \
> +         result = 1;                                                   \
> +       }                                                               \
> +    }                                                                  \
> +  return result;                                                       \
> +}
> +
> +TEST_FUNC (float_test, float, f)
> +TEST_FUNC (double_test, double, )
> +TEST_FUNC (ldouble_test, long double, l)
> +
> +static int
> +do_test (void)
> +{
> +  int result = float_test ();
> +  result |= double_test ();
> +  result |= ldouble_test ();
> +  if (!any_supported)
> +    return 77;
> +  return result;
> +}
> +
> +#include <support/test-driver.c>
> --
> 2.34.1
>

LGTM.

Reviewed-by: H.J. Lu <hjl.tools@gmail.com>

Thanks.

-- 
H.J.

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

* Re: [PATCH v2 02/10] math: Add test to check if floor raise inexact floating-point exception
  2024-04-03 12:11 ` [PATCH v2 02/10] math: Add test to check if floor " Adhemerval Zanella
@ 2024-04-03 12:55   ` H.J. Lu
  0 siblings, 0 replies; 21+ messages in thread
From: H.J. Lu @ 2024-04-03 12:55 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

On Wed, Apr 3, 2024 at 5:11 AM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
> It is not allowed anymore on ISO C23.
> ---
>  math/Makefile              |  4 ++
>  math/test-floor-except-2.c | 67 ++++++++++++++++++++++++++++++
>  math/test-floor-except.c   | 85 ++++++++++++++++++++++++++++++++++++++
>  3 files changed, 156 insertions(+)
>  create mode 100644 math/test-floor-except-2.c
>  create mode 100644 math/test-floor-except.c
>
> diff --git a/math/Makefile b/math/Makefile
> index 1017026d23..8ab2582d69 100644
> --- a/math/Makefile
> +++ b/math/Makefile
> @@ -512,6 +512,8 @@ tests = \
>    test-fetestexceptflag \
>    test-fexcept \
>    test-fexcept-traps \
> +  test-floor-except \
> +  test-floor-except-2 \
>    test-flt-eval-method \
>    test-fp-ilogb-constants \
>    test-fp-llogb-constants \
> @@ -993,6 +995,8 @@ CFLAGS-test-nan-const.c += -fno-builtin
>
>  CFLAGS-test-ceil-except.c += -fno-builtin
>  CFLAGS-test-ceil-except-2.c += -fno-builtin
> +CFLAGS-test-floor-except.c += -fno-builtin
> +CFLAGS-test-floor-except-2.c += -fno-builtin
>
>  include ../Rules
>
> diff --git a/math/test-floor-except-2.c b/math/test-floor-except-2.c
> new file mode 100644
> index 0000000000..d99e835909
> --- /dev/null
> +++ b/math/test-floor-except-2.c
> @@ -0,0 +1,67 @@
> +/* Test floor functions do not disable exception traps.
> +   Copyright (C) 2024 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 <fenv.h>
> +#include <math.h>
> +#include <stdio.h>
> +
> +#ifndef FE_INEXACT
> +# define FE_INEXACT 0
> +#endif
> +
> +#define TEST_FUNC(NAME, FLOAT, SUFFIX)                                 \
> +static int                                                             \
> +NAME (void)                                                            \
> +{                                                                      \
> +  int result = 0;                                                      \
> +  volatile FLOAT a, b __attribute__ ((unused));                                \
> +  a = 1.5;                                                             \
> +  /* floor must work when traps on "inexact" are enabled.  */  \
> +  b = floor ## SUFFIX (a);                                             \
> +  /* And it must have left those traps enabled.  */                    \
> +  if (fegetexcept () == FE_INEXACT)                                    \
> +    puts ("PASS: " #FLOAT);                                            \
> +  else                                                                 \
> +    {                                                                  \
> +      puts ("FAIL: " #FLOAT);                                          \
> +      result = 1;                                                      \
> +    }                                                                  \
> +  return result;                                                       \
> +}
> +
> +TEST_FUNC (float_test, float, f)
> +TEST_FUNC (double_test, double, )
> +TEST_FUNC (ldouble_test, long double, l)
> +
> +static int
> +do_test (void)
> +{
> +  if (feenableexcept (FE_INEXACT) == -1)
> +    {
> +      puts ("enabling FE_INEXACT traps failed, cannot test");
> +      return 77;
> +    }
> +  int result = float_test ();
> +  feenableexcept (FE_INEXACT);
> +  result |= double_test ();
> +  feenableexcept (FE_INEXACT);
> +  result |= ldouble_test ();
> +  return result;
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/math/test-floor-except.c b/math/test-floor-except.c
> new file mode 100644
> index 0000000000..a957c059e2
> --- /dev/null
> +++ b/math/test-floor-except.c
> @@ -0,0 +1,85 @@
> +/* Test floor functions do not clear exceptions.
> +   Copyright (C) 2024 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 <fenv.h>
> +#include <math.h>
> +#include <stdbool.h>
> +#include <stdio.h>
> +
> +#include <math-tests.h>
> +
> +#ifndef FE_INVALID
> +# define FE_INVALID 0
> +#endif
> +
> +static bool any_supported = false;
> +
> +#define TEST_FUNC(NAME, FLOAT, SUFFIX)                                 \
> +static int                                                             \
> +NAME (void)                                                            \
> +{                                                                      \
> +  int result = 0;                                                      \
> +  if (!EXCEPTION_TESTS (FLOAT))                                                \
> +    return 0;                                                          \
> +  any_supported = true;                                                        \
> +  volatile FLOAT a, b __attribute__ ((unused));                                \
> +  a = 1.0;                                                             \
> +  /* floor must not clear already-raised exceptions.  */               \
> +  feraiseexcept (FE_ALL_EXCEPT);                                       \
> +  b = floor ## SUFFIX (a);                                             \
> +  if (fetestexcept (FE_ALL_EXCEPT) == FE_ALL_EXCEPT)                   \
> +    puts ("PASS: " #FLOAT);                                            \
> +  else                                                                 \
> +    {                                                                  \
> +      puts ("FAIL: " #FLOAT);                                          \
> +      result = 1;                                                      \
> +    }                                                                  \
> +  /* But it mustn't lose exceptions from sNaN arguments.  */           \
> +  if (SNAN_TESTS (FLOAT))                                              \
> +    {                                                                  \
> +      static volatile FLOAT snan = __builtin_nans ## SUFFIX ("");      \
> +      volatile FLOAT c __attribute__ ((unused));                       \
> +      feclearexcept (FE_ALL_EXCEPT);                                   \
> +      c = floor ## SUFFIX (snan);                                      \
> +      if (fetestexcept (FE_INVALID) == FE_INVALID)                     \
> +       puts ("PASS: " #FLOAT " sNaN");                                 \
> +      else                                                             \
> +       {                                                               \
> +         puts ("FAIL: " #FLOAT " sNaN");                               \
> +         result = 1;                                                   \
> +       }                                                               \
> +    }                                                                  \
> +  return result;                                                       \
> +}
> +
> +TEST_FUNC (float_test, float, f)
> +TEST_FUNC (double_test, double, )
> +TEST_FUNC (ldouble_test, long double, l)
> +
> +static int
> +do_test (void)
> +{
> +  int result = float_test ();
> +  result |= double_test ();
> +  result |= ldouble_test ();
> +  if (!any_supported)
> +    return 77;
> +  return result;
> +}
> +
> +#include <support/test-driver.c>
> --
> 2.34.1
>

LGTM.

Reviewed-by: H.J. Lu <hjl.tools@gmail.com>

Thanks.

-- 
H.J.

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

* Re: [PATCH v2 03/10] math: Add test to check if trunc raise inexact floating-point exception
  2024-04-03 12:11 ` [PATCH v2 03/10] math: Add test to check if trunc " Adhemerval Zanella
@ 2024-04-03 12:55   ` H.J. Lu
  0 siblings, 0 replies; 21+ messages in thread
From: H.J. Lu @ 2024-04-03 12:55 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

On Wed, Apr 3, 2024 at 5:11 AM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
> It is not allowed anymore on ISO C23.
> ---
>  math/Makefile              |  4 ++
>  math/test-trunc-except-2.c | 67 ++++++++++++++++++++++++++++++
>  math/test-trunc-except.c   | 85 ++++++++++++++++++++++++++++++++++++++
>  3 files changed, 156 insertions(+)
>  create mode 100644 math/test-trunc-except-2.c
>  create mode 100644 math/test-trunc-except.c
>
> diff --git a/math/Makefile b/math/Makefile
> index 8ab2582d69..32e3001ec6 100644
> --- a/math/Makefile
> +++ b/math/Makefile
> @@ -541,6 +541,8 @@ tests = \
>    test-tgmath-int \
>    test-tgmath-ret \
>    test-tgmath2 \
> +  test-trunc-except \
> +  test-trunc-except-2 \
>    tst-CMPLX \
>    tst-CMPLX2 \
>    tst-definitions \
> @@ -997,6 +999,8 @@ CFLAGS-test-ceil-except.c += -fno-builtin
>  CFLAGS-test-ceil-except-2.c += -fno-builtin
>  CFLAGS-test-floor-except.c += -fno-builtin
>  CFLAGS-test-floor-except-2.c += -fno-builtin
> +CFLAGS-test-trunc-except.c += -fno-builtin
> +CFLAGS-test-trunc-except-2.c += -fno-builtin
>
>  include ../Rules
>
> diff --git a/math/test-trunc-except-2.c b/math/test-trunc-except-2.c
> new file mode 100644
> index 0000000000..8933c6ab41
> --- /dev/null
> +++ b/math/test-trunc-except-2.c
> @@ -0,0 +1,67 @@
> +/* Test trunc functions do not disable exception traps.
> +   Copyright (C) 2024 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 <fenv.h>
> +#include <math.h>
> +#include <stdio.h>
> +
> +#ifndef FE_INEXACT
> +# define FE_INEXACT 0
> +#endif
> +
> +#define TEST_FUNC(NAME, FLOAT, SUFFIX)                                 \
> +static int                                                             \
> +NAME (void)                                                            \
> +{                                                                      \
> +  int result = 0;                                                      \
> +  volatile FLOAT a, b __attribute__ ((unused));                                \
> +  a = 1.5;                                                             \
> +  /* trunc must work when traps on "inexact" are enabled.  */  \
> +  b = trunc ## SUFFIX (a);                                             \
> +  /* And it must have left those traps enabled.  */                    \
> +  if (fegetexcept () == FE_INEXACT)                                    \
> +    puts ("PASS: " #FLOAT);                                            \
> +  else                                                                 \
> +    {                                                                  \
> +      puts ("FAIL: " #FLOAT);                                          \
> +      result = 1;                                                      \
> +    }                                                                  \
> +  return result;                                                       \
> +}
> +
> +TEST_FUNC (float_test, float, f)
> +TEST_FUNC (double_test, double, )
> +TEST_FUNC (ldouble_test, long double, l)
> +
> +static int
> +do_test (void)
> +{
> +  if (feenableexcept (FE_INEXACT) == -1)
> +    {
> +      puts ("enabling FE_INEXACT traps failed, cannot test");
> +      return 77;
> +    }
> +  int result = float_test ();
> +  feenableexcept (FE_INEXACT);
> +  result |= double_test ();
> +  feenableexcept (FE_INEXACT);
> +  result |= ldouble_test ();
> +  return result;
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/math/test-trunc-except.c b/math/test-trunc-except.c
> new file mode 100644
> index 0000000000..ff909d79ed
> --- /dev/null
> +++ b/math/test-trunc-except.c
> @@ -0,0 +1,85 @@
> +/* Test trunc functions do not clear exceptions.
> +   Copyright (C) 2024 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 <fenv.h>
> +#include <math.h>
> +#include <stdbool.h>
> +#include <stdio.h>
> +
> +#include <math-tests.h>
> +
> +#ifndef FE_INVALID
> +# define FE_INVALID 0
> +#endif
> +
> +static bool any_supported = false;
> +
> +#define TEST_FUNC(NAME, FLOAT, SUFFIX)                                 \
> +static int                                                             \
> +NAME (void)                                                            \
> +{                                                                      \
> +  int result = 0;                                                      \
> +  if (!EXCEPTION_TESTS (FLOAT))                                                \
> +    return 0;                                                          \
> +  any_supported = true;                                                        \
> +  volatile FLOAT a, b __attribute__ ((unused));                                \
> +  a = 1.0;                                                             \
> +  /* trunc must not clear already-raised exceptions.  */               \
> +  feraiseexcept (FE_ALL_EXCEPT);                                       \
> +  b = trunc ## SUFFIX (a);                                             \
> +  if (fetestexcept (FE_ALL_EXCEPT) == FE_ALL_EXCEPT)                   \
> +    puts ("PASS: " #FLOAT);                                            \
> +  else                                                                 \
> +    {                                                                  \
> +      puts ("FAIL: " #FLOAT);                                          \
> +      result = 1;                                                      \
> +    }                                                                  \
> +  /* But it mustn't lose exceptions from sNaN arguments.  */           \
> +  if (SNAN_TESTS (FLOAT))                                              \
> +    {                                                                  \
> +      static volatile FLOAT snan = __builtin_nans ## SUFFIX ("");      \
> +      volatile FLOAT c __attribute__ ((unused));                       \
> +      feclearexcept (FE_ALL_EXCEPT);                                   \
> +      c = trunc ## SUFFIX (snan);                                      \
> +      if (fetestexcept (FE_INVALID) == FE_INVALID)                     \
> +       puts ("PASS: " #FLOAT " sNaN");                                 \
> +      else                                                             \
> +       {                                                               \
> +         puts ("FAIL: " #FLOAT " sNaN");                               \
> +         result = 1;                                                   \
> +       }                                                               \
> +    }                                                                  \
> +  return result;                                                       \
> +}
> +
> +TEST_FUNC (float_test, float, f)
> +TEST_FUNC (double_test, double, )
> +TEST_FUNC (ldouble_test, long double, l)
> +
> +static int
> +do_test (void)
> +{
> +  int result = float_test ();
> +  result |= double_test ();
> +  result |= ldouble_test ();
> +  if (!any_supported)
> +    return 77;
> +  return result;
> +}
> +
> +#include <support/test-driver.c>
> --
> 2.34.1
>

LGTM.

Reviewed-by: H.J. Lu <hjl.tools@gmail.com>

Thanks.

-- 
H.J.

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

* Re: [PATCH v2 04/10] math: Add test to check if round raise inexact floating-point exception
  2024-04-03 12:11 ` [PATCH v2 04/10] math: Add test to check if round " Adhemerval Zanella
@ 2024-04-03 12:56   ` H.J. Lu
  0 siblings, 0 replies; 21+ messages in thread
From: H.J. Lu @ 2024-04-03 12:56 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

On Wed, Apr 3, 2024 at 5:12 AM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
> It is not allowed anymore on ISO C23.
> ---
>  math/Makefile              |  4 ++
>  math/test-round-except-2.c | 67 ++++++++++++++++++++++++++++++
>  math/test-round-except.c   | 85 ++++++++++++++++++++++++++++++++++++++
>  3 files changed, 156 insertions(+)
>  create mode 100644 math/test-round-except-2.c
>  create mode 100644 math/test-round-except.c
>
> diff --git a/math/Makefile b/math/Makefile
> index 32e3001ec6..35a148a66c 100644
> --- a/math/Makefile
> +++ b/math/Makefile
> @@ -530,6 +530,8 @@ tests = \
>    test-nearbyint-except \
>    test-nearbyint-except-2 \
>    test-powl \
> +  test-round-except \
> +  test-round-except-2 \
>    test-signgam-uchar \
>    test-signgam-uchar-init \
>    test-signgam-uint \
> @@ -1001,6 +1003,8 @@ CFLAGS-test-floor-except.c += -fno-builtin
>  CFLAGS-test-floor-except-2.c += -fno-builtin
>  CFLAGS-test-trunc-except.c += -fno-builtin
>  CFLAGS-test-trunc-except-2.c += -fno-builtin
> +CFLAGS-test-round-except.c += -fno-builtin
> +CFLAGS-test-round-except-2.c += -fno-builtin
>
>  include ../Rules
>
> diff --git a/math/test-round-except-2.c b/math/test-round-except-2.c
> new file mode 100644
> index 0000000000..5281b919b0
> --- /dev/null
> +++ b/math/test-round-except-2.c
> @@ -0,0 +1,67 @@
> +/* Test round functions do not disable exception traps.
> +   Copyright (C) 2024 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 <fenv.h>
> +#include <math.h>
> +#include <stdio.h>
> +
> +#ifndef FE_INEXACT
> +# define FE_INEXACT 0
> +#endif
> +
> +#define TEST_FUNC(NAME, FLOAT, SUFFIX)                                 \
> +static int                                                             \
> +NAME (void)                                                            \
> +{                                                                      \
> +  int result = 0;                                                      \
> +  volatile FLOAT a, b __attribute__ ((unused));                                \
> +  a = 1.5;                                                             \
> +  /* round must work when traps on "inexact" are enabled.  */  \
> +  b = round ## SUFFIX (a);                                             \
> +  /* And it must have left those traps enabled.  */                    \
> +  if (fegetexcept () == FE_INEXACT)                                    \
> +    puts ("PASS: " #FLOAT);                                            \
> +  else                                                                 \
> +    {                                                                  \
> +      puts ("FAIL: " #FLOAT);                                          \
> +      result = 1;                                                      \
> +    }                                                                  \
> +  return result;                                                       \
> +}
> +
> +TEST_FUNC (float_test, float, f)
> +TEST_FUNC (double_test, double, )
> +TEST_FUNC (ldouble_test, long double, l)
> +
> +static int
> +do_test (void)
> +{
> +  if (feenableexcept (FE_INEXACT) == -1)
> +    {
> +      puts ("enabling FE_INEXACT traps failed, cannot test");
> +      return 77;
> +    }
> +  int result = float_test ();
> +  feenableexcept (FE_INEXACT);
> +  result |= double_test ();
> +  feenableexcept (FE_INEXACT);
> +  result |= ldouble_test ();
> +  return result;
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/math/test-round-except.c b/math/test-round-except.c
> new file mode 100644
> index 0000000000..c4515daf89
> --- /dev/null
> +++ b/math/test-round-except.c
> @@ -0,0 +1,85 @@
> +/* Test round functions do not clear exceptions.
> +   Copyright (C) 2024 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 <fenv.h>
> +#include <math.h>
> +#include <stdbool.h>
> +#include <stdio.h>
> +
> +#include <math-tests.h>
> +
> +#ifndef FE_INVALID
> +# define FE_INVALID 0
> +#endif
> +
> +static bool any_supported = false;
> +
> +#define TEST_FUNC(NAME, FLOAT, SUFFIX)                                 \
> +static int                                                             \
> +NAME (void)                                                            \
> +{                                                                      \
> +  int result = 0;                                                      \
> +  if (!EXCEPTION_TESTS (FLOAT))                                                \
> +    return 0;                                                          \
> +  any_supported = true;                                                        \
> +  volatile FLOAT a, b __attribute__ ((unused));                                \
> +  a = 1.0;                                                             \
> +  /* round must not clear already-raised exceptions.  */               \
> +  feraiseexcept (FE_ALL_EXCEPT);                                       \
> +  b = round ## SUFFIX (a);                                             \
> +  if (fetestexcept (FE_ALL_EXCEPT) == FE_ALL_EXCEPT)                   \
> +    puts ("PASS: " #FLOAT);                                            \
> +  else                                                                 \
> +    {                                                                  \
> +      puts ("FAIL: " #FLOAT);                                          \
> +      result = 1;                                                      \
> +    }                                                                  \
> +  /* But it mustn't lose exceptions from sNaN arguments.  */           \
> +  if (SNAN_TESTS (FLOAT))                                              \
> +    {                                                                  \
> +      static volatile FLOAT snan = __builtin_nans ## SUFFIX ("");      \
> +      volatile FLOAT c __attribute__ ((unused));                       \
> +      feclearexcept (FE_ALL_EXCEPT);                                   \
> +      c = round ## SUFFIX (snan);                                      \
> +      if (fetestexcept (FE_INVALID) == FE_INVALID)                     \
> +       puts ("PASS: " #FLOAT " sNaN");                                 \
> +      else                                                             \
> +       {                                                               \
> +         puts ("FAIL: " #FLOAT " sNaN");                               \
> +         result = 1;                                                   \
> +       }                                                               \
> +    }                                                                  \
> +  return result;                                                       \
> +}
> +
> +TEST_FUNC (float_test, float, f)
> +TEST_FUNC (double_test, double, )
> +TEST_FUNC (ldouble_test, long double, l)
> +
> +static int
> +do_test (void)
> +{
> +  int result = float_test ();
> +  result |= double_test ();
> +  result |= ldouble_test ();
> +  if (!any_supported)
> +    return 77;
> +  return result;
> +}
> +
> +#include <support/test-driver.c>
> --
> 2.34.1
>

LGTM.

Reviewed-by: H.J. Lu <hjl.tools@gmail.com>

Thanks.

-- 
H.J.

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

* Re: [PATCH v2 05/10] x86: Do not raise inexact exception on ceill
  2024-04-03 12:11 ` [PATCH v2 05/10] x86: Do not raise inexact exception on ceill Adhemerval Zanella
@ 2024-04-03 13:04   ` H.J. Lu
  2024-04-03 13:15     ` Adhemerval Zanella Netto
  0 siblings, 1 reply; 21+ messages in thread
From: H.J. Lu @ 2024-04-03 13:04 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

On Wed, Apr 3, 2024 at 5:12 AM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
> It is not allowed anymore on ISO C23.
>
> Checked on x86_64-linux-gnu and i686-linux-gnu.
> ---
>  sysdeps/i386/fpu/s_ceill.S   | 39 ------------------------------------
>  sysdeps/x86/fpu/s_ceill.c    | 38 +++++++++++++++++++++++++++++++++++
>  sysdeps/x86_64/fpu/s_ceill.S | 34 -------------------------------
>  3 files changed, 38 insertions(+), 73 deletions(-)
>  delete mode 100644 sysdeps/i386/fpu/s_ceill.S
>  create mode 100644 sysdeps/x86/fpu/s_ceill.c
>  delete mode 100644 sysdeps/x86_64/fpu/s_ceill.S
>
> diff --git a/sysdeps/i386/fpu/s_ceill.S b/sysdeps/i386/fpu/s_ceill.S
> deleted file mode 100644
> index a551fce7f9..0000000000
> --- a/sysdeps/i386/fpu/s_ceill.S
> +++ /dev/null
> @@ -1,39 +0,0 @@
> -/*
> - * Public domain.
> - */
> -
> -#include <libm-alias-ldouble.h>
> -#include <machine/asm.h>
> -
> -RCSID("$NetBSD: $")
> -
> -ENTRY(__ceill)
> -       fldt    4(%esp)
> -       subl    $32,%esp
> -       cfi_adjust_cfa_offset (32)
> -
> -       fnstenv 4(%esp)                 /* store fpu environment */
> -
> -       /* We use here %edx although only the low 1 bits are defined.
> -          But none of the operations should care and they are faster
> -          than the 16 bit operations.  */
> -       movl    $0x0800,%edx            /* round towards +oo */
> -       orl     4(%esp),%edx
> -       andl    $0xfbff,%edx
> -       movl    %edx,(%esp)
> -       fldcw   (%esp)                  /* load modified control word */
> -
> -       frndint                         /* round */
> -
> -       /* Preserve "invalid" exceptions from sNaN input.  */
> -       fnstsw
> -       andl    $0x1, %eax
> -       orl     %eax, 8(%esp)
> -
> -       fldenv  4(%esp)                 /* restore original environment */
> -
> -       addl    $32,%esp
> -       cfi_adjust_cfa_offset (-32)
> -       ret
> -END (__ceill)
> -libm_alias_ldouble (__ceil, ceil)
> diff --git a/sysdeps/x86/fpu/s_ceill.c b/sysdeps/x86/fpu/s_ceill.c
> new file mode 100644
> index 0000000000..6ccc9d84d4
> --- /dev/null
> +++ b/sysdeps/x86/fpu/s_ceill.c
> @@ -0,0 +1,38 @@
> +/* Return smallest integral value not less than argument.  x86 version.
> +   Copyright (C) 2024 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/>.  */
> +
> +#define NO_MATH_REDIRECT
> +#include <math.h>
> +#include <fenv_private.h>
> +#include <libm-alias-ldouble.h>
> +
> +long double
> +__ceill (long double x)
> +{
> +  fenv_t fenv;
> +  long double r;
> +
> +  libc_feholdexcept_setround_387 (&fenv, FE_UPWARD);
> +  asm volatile ("frndint" : "=t" (r) : "0" (x));
> +  /* Preserve "invalid" exceptions from sNaN input.  */
> +  fenv.__status_word |= libc_fetestexcept_387 (FE_INVALID);
> +  libc_fesetenv_387 (&fenv);
> +

Since all these newly added functions are almost identical,
should we use a template instead of repeating the similar
code sequence? Something like

TYPE
FUNC (TYPE x)
{
  fenv_t fenv;
  TYPE r;

  libc_feholdexcept_setround_387 (&fenv, FE_OPTION);
  asm volatile ("frndint" : "=t" (r) : "0" (x));
  /* Preserve "invalid" exceptions from sNaN input.  */
  fenv.__status_word |= libc_fetestexcept_387 (FE_INVALID);
  libc_fesetenv_387 (&fenv);

  return r;

}

> +  return r;
> +}
> +libm_alias_ldouble (__ceil, ceil)
> diff --git a/sysdeps/x86_64/fpu/s_ceill.S b/sysdeps/x86_64/fpu/s_ceill.S
> deleted file mode 100644
> index 16dbecd56d..0000000000
> --- a/sysdeps/x86_64/fpu/s_ceill.S
> +++ /dev/null
> @@ -1,34 +0,0 @@
> -/*
> - * Public domain.
> - */
> -
> -#include <libm-alias-ldouble.h>
> -#include <machine/asm.h>
> -
> -
> -ENTRY(__ceill)
> -       fldt    8(%rsp)
> -
> -       fnstenv -28(%rsp)               /* store fpu environment */
> -
> -       /* We use here %edx although only the low 1 bits are defined.
> -          But none of the operations should care and they are faster
> -          than the 16 bit operations.  */
> -       movl    $0x0800,%edx            /* round towards +oo */
> -       orl     -28(%rsp),%edx
> -       andl    $0xfbff,%edx
> -       movl    %edx,-32(%rsp)
> -       fldcw   -32(%rsp)               /* load modified control word */
> -
> -       frndint                         /* round */
> -
> -       /* Preserve "invalid" exceptions from sNaN input.  */
> -       fnstsw
> -       andl    $0x1, %eax
> -       orl     %eax, -24(%rsp)
> -
> -       fldenv  -28(%rsp)               /* restore original environment */
> -
> -       ret
> -END (__ceill)
> -libm_alias_ldouble (__ceil, ceil)
> --
> 2.34.1
>


--
H.J.

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

* Re: [PATCH v2 05/10] x86: Do not raise inexact exception on ceill
  2024-04-03 13:04   ` H.J. Lu
@ 2024-04-03 13:15     ` Adhemerval Zanella Netto
  2024-04-03 13:28       ` H.J. Lu
  0 siblings, 1 reply; 21+ messages in thread
From: Adhemerval Zanella Netto @ 2024-04-03 13:15 UTC (permalink / raw)
  To: H.J. Lu; +Cc: libc-alpha



On 03/04/24 10:04, H.J. Lu wrote:
> On Wed, Apr 3, 2024 at 5:12 AM Adhemerval Zanella
> <adhemerval.zanella@linaro.org> wrote:
>>
>> It is not allowed anymore on ISO C23.
>>
>> Checked on x86_64-linux-gnu and i686-linux-gnu.
>> ---
>>  sysdeps/i386/fpu/s_ceill.S   | 39 ------------------------------------
>>  sysdeps/x86/fpu/s_ceill.c    | 38 +++++++++++++++++++++++++++++++++++
>>  sysdeps/x86_64/fpu/s_ceill.S | 34 -------------------------------
>>  3 files changed, 38 insertions(+), 73 deletions(-)
>>  delete mode 100644 sysdeps/i386/fpu/s_ceill.S
>>  create mode 100644 sysdeps/x86/fpu/s_ceill.c
>>  delete mode 100644 sysdeps/x86_64/fpu/s_ceill.S
>>
>> diff --git a/sysdeps/i386/fpu/s_ceill.S b/sysdeps/i386/fpu/s_ceill.S
>> deleted file mode 100644
>> index a551fce7f9..0000000000
>> --- a/sysdeps/i386/fpu/s_ceill.S
>> +++ /dev/null
>> @@ -1,39 +0,0 @@
>> -/*
>> - * Public domain.
>> - */
>> -
>> -#include <libm-alias-ldouble.h>
>> -#include <machine/asm.h>
>> -
>> -RCSID("$NetBSD: $")
>> -
>> -ENTRY(__ceill)
>> -       fldt    4(%esp)
>> -       subl    $32,%esp
>> -       cfi_adjust_cfa_offset (32)
>> -
>> -       fnstenv 4(%esp)                 /* store fpu environment */
>> -
>> -       /* We use here %edx although only the low 1 bits are defined.
>> -          But none of the operations should care and they are faster
>> -          than the 16 bit operations.  */
>> -       movl    $0x0800,%edx            /* round towards +oo */
>> -       orl     4(%esp),%edx
>> -       andl    $0xfbff,%edx
>> -       movl    %edx,(%esp)
>> -       fldcw   (%esp)                  /* load modified control word */
>> -
>> -       frndint                         /* round */
>> -
>> -       /* Preserve "invalid" exceptions from sNaN input.  */
>> -       fnstsw
>> -       andl    $0x1, %eax
>> -       orl     %eax, 8(%esp)
>> -
>> -       fldenv  4(%esp)                 /* restore original environment */
>> -
>> -       addl    $32,%esp
>> -       cfi_adjust_cfa_offset (-32)
>> -       ret
>> -END (__ceill)
>> -libm_alias_ldouble (__ceil, ceil)
>> diff --git a/sysdeps/x86/fpu/s_ceill.c b/sysdeps/x86/fpu/s_ceill.c
>> new file mode 100644
>> index 0000000000..6ccc9d84d4
>> --- /dev/null
>> +++ b/sysdeps/x86/fpu/s_ceill.c
>> @@ -0,0 +1,38 @@
>> +/* Return smallest integral value not less than argument.  x86 version.
>> +   Copyright (C) 2024 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/>.  */
>> +
>> +#define NO_MATH_REDIRECT
>> +#include <math.h>
>> +#include <fenv_private.h>
>> +#include <libm-alias-ldouble.h>
>> +
>> +long double
>> +__ceill (long double x)
>> +{
>> +  fenv_t fenv;
>> +  long double r;
>> +
>> +  libc_feholdexcept_setround_387 (&fenv, FE_UPWARD);
>> +  asm volatile ("frndint" : "=t" (r) : "0" (x));
>> +  /* Preserve "invalid" exceptions from sNaN input.  */
>> +  fenv.__status_word |= libc_fetestexcept_387 (FE_INVALID);
>> +  libc_fesetenv_387 (&fenv);
>> +
> 
> Since all these newly added functions are almost identical,
> should we use a template instead of repeating the similar
> code sequence? Something like
> 
> TYPE
> FUNC (TYPE x)
> {
>   fenv_t fenv;
>   TYPE r;
> 
>   libc_feholdexcept_setround_387 (&fenv, FE_OPTION);
>   asm volatile ("frndint" : "=t" (r) : "0" (x));
>   /* Preserve "invalid" exceptions from sNaN input.  */
>   fenv.__status_word |= libc_fetestexcept_387 (FE_INVALID);
>   libc_fesetenv_387 (&fenv);
> 
>   return r;
> 
> }

Sounds reasonable, I will update the patch.

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

* Re: [PATCH v2 05/10] x86: Do not raise inexact exception on ceill
  2024-04-03 13:15     ` Adhemerval Zanella Netto
@ 2024-04-03 13:28       ` H.J. Lu
  0 siblings, 0 replies; 21+ messages in thread
From: H.J. Lu @ 2024-04-03 13:28 UTC (permalink / raw)
  To: Adhemerval Zanella Netto; +Cc: libc-alpha

On Wed, Apr 3, 2024 at 6:15 AM Adhemerval Zanella Netto
<adhemerval.zanella@linaro.org> wrote:
>
>
>
> On 03/04/24 10:04, H.J. Lu wrote:
> > On Wed, Apr 3, 2024 at 5:12 AM Adhemerval Zanella
> > <adhemerval.zanella@linaro.org> wrote:
> >>
> >> It is not allowed anymore on ISO C23.
> >>
> >> Checked on x86_64-linux-gnu and i686-linux-gnu.
> >> ---
> >>  sysdeps/i386/fpu/s_ceill.S   | 39 ------------------------------------
> >>  sysdeps/x86/fpu/s_ceill.c    | 38 +++++++++++++++++++++++++++++++++++
> >>  sysdeps/x86_64/fpu/s_ceill.S | 34 -------------------------------
> >>  3 files changed, 38 insertions(+), 73 deletions(-)
> >>  delete mode 100644 sysdeps/i386/fpu/s_ceill.S
> >>  create mode 100644 sysdeps/x86/fpu/s_ceill.c
> >>  delete mode 100644 sysdeps/x86_64/fpu/s_ceill.S
> >>
> >> diff --git a/sysdeps/i386/fpu/s_ceill.S b/sysdeps/i386/fpu/s_ceill.S
> >> deleted file mode 100644
> >> index a551fce7f9..0000000000
> >> --- a/sysdeps/i386/fpu/s_ceill.S
> >> +++ /dev/null
> >> @@ -1,39 +0,0 @@
> >> -/*
> >> - * Public domain.
> >> - */
> >> -
> >> -#include <libm-alias-ldouble.h>
> >> -#include <machine/asm.h>
> >> -
> >> -RCSID("$NetBSD: $")
> >> -
> >> -ENTRY(__ceill)
> >> -       fldt    4(%esp)
> >> -       subl    $32,%esp
> >> -       cfi_adjust_cfa_offset (32)
> >> -
> >> -       fnstenv 4(%esp)                 /* store fpu environment */
> >> -
> >> -       /* We use here %edx although only the low 1 bits are defined.
> >> -          But none of the operations should care and they are faster
> >> -          than the 16 bit operations.  */
> >> -       movl    $0x0800,%edx            /* round towards +oo */
> >> -       orl     4(%esp),%edx
> >> -       andl    $0xfbff,%edx
> >> -       movl    %edx,(%esp)
> >> -       fldcw   (%esp)                  /* load modified control word */
> >> -
> >> -       frndint                         /* round */
> >> -
> >> -       /* Preserve "invalid" exceptions from sNaN input.  */
> >> -       fnstsw
> >> -       andl    $0x1, %eax
> >> -       orl     %eax, 8(%esp)
> >> -
> >> -       fldenv  4(%esp)                 /* restore original environment */
> >> -
> >> -       addl    $32,%esp
> >> -       cfi_adjust_cfa_offset (-32)
> >> -       ret
> >> -END (__ceill)
> >> -libm_alias_ldouble (__ceil, ceil)
> >> diff --git a/sysdeps/x86/fpu/s_ceill.c b/sysdeps/x86/fpu/s_ceill.c
> >> new file mode 100644
> >> index 0000000000..6ccc9d84d4
> >> --- /dev/null
> >> +++ b/sysdeps/x86/fpu/s_ceill.c
> >> @@ -0,0 +1,38 @@
> >> +/* Return smallest integral value not less than argument.  x86 version.
> >> +   Copyright (C) 2024 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/>.  */
> >> +
> >> +#define NO_MATH_REDIRECT
> >> +#include <math.h>
> >> +#include <fenv_private.h>
> >> +#include <libm-alias-ldouble.h>
> >> +
> >> +long double
> >> +__ceill (long double x)
> >> +{
> >> +  fenv_t fenv;
> >> +  long double r;
> >> +
> >> +  libc_feholdexcept_setround_387 (&fenv, FE_UPWARD);
> >> +  asm volatile ("frndint" : "=t" (r) : "0" (x));
> >> +  /* Preserve "invalid" exceptions from sNaN input.  */
> >> +  fenv.__status_word |= libc_fetestexcept_387 (FE_INVALID);
> >> +  libc_fesetenv_387 (&fenv);
> >> +
> >
> > Since all these newly added functions are almost identical,
> > should we use a template instead of repeating the similar
> > code sequence? Something like
> >
> > TYPE
> > FUNC (TYPE x)
> > {
> >   fenv_t fenv;
> >   TYPE r;
> >
> >   libc_feholdexcept_setround_387 (&fenv, FE_OPTION);
> >   asm volatile ("frndint" : "=t" (r) : "0" (x));
> >   /* Preserve "invalid" exceptions from sNaN input.  */
> >   fenv.__status_word |= libc_fetestexcept_387 (FE_INVALID);
> >   libc_fesetenv_387 (&fenv);
> >
> >   return r;
> >
> > }
>
> Sounds reasonable, I will update the patch.

Please include "387" or something similar in the template
filename since it should only be used with 387 implementation.

Thanks.

-- 
H.J.

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

* Re: [PATCH v2 00/10] Improve rounding to interger function for C23
  2024-04-03 12:11 [PATCH v2 00/10] Improve rounding to interger function for C23 Adhemerval Zanella
                   ` (9 preceding siblings ...)
  2024-04-03 12:11 ` [PATCH v2 10/10] i386: Do not raise inexact exception on trunc/truncf Adhemerval Zanella
@ 2024-04-03 15:03 ` Joseph Myers
  2024-04-03 17:10   ` Adhemerval Zanella Netto
  10 siblings, 1 reply; 21+ messages in thread
From: Joseph Myers @ 2024-04-03 15:03 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, H . J . Lu

On Wed, 3 Apr 2024, Adhemerval Zanella wrote:

> As indicated by GCC documentation [1], ISO C23 does not allow that C
> bindings ceil, floor, round, and trunc (in all floating point formats)
> to raise inexact exceptions (different than ISO C99/C11 where this is
> allowed).
> 
> A recent MIPS patch to used some arch-specific instructions raised this
> issue [1] and it was not caught because there was no proper testing. By
> adding the missing tests, some implementations do indeed raise inexact
> exceptions. 

There is testing that, in the terminology used by IEEE 754, the operations 
do not raise the exception flag (the result of default exception handling 
when the exception is signaled).  This is done through 
NO_INEXACT_EXCEPTION in libm-test-*.inc.

What is not tested is specifically quality of implementation when 
exception traps are enabled (a GNU extension outside the scope of the C 
standard).

I think that as a user-visible fix, there should be a bug filed in 
Bugzilla for this issue (that can then be marked FIXED so it goes in the 
automatically generated list of bugs fixed in the next release).

-- 
Joseph S. Myers
josmyers@redhat.com


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

* Re: [PATCH v2 00/10] Improve rounding to interger function for C23
  2024-04-03 15:03 ` [PATCH v2 00/10] Improve rounding to interger function for C23 Joseph Myers
@ 2024-04-03 17:10   ` Adhemerval Zanella Netto
  2024-04-04  5:25     ` Paul Zimmermann
  0 siblings, 1 reply; 21+ messages in thread
From: Adhemerval Zanella Netto @ 2024-04-03 17:10 UTC (permalink / raw)
  To: Joseph Myers; +Cc: libc-alpha, H . J . Lu



On 03/04/24 12:03, Joseph Myers wrote:
> On Wed, 3 Apr 2024, Adhemerval Zanella wrote:
> 
>> As indicated by GCC documentation [1], ISO C23 does not allow that C
>> bindings ceil, floor, round, and trunc (in all floating point formats)
>> to raise inexact exceptions (different than ISO C99/C11 where this is
>> allowed).
>>
>> A recent MIPS patch to used some arch-specific instructions raised this
>> issue [1] and it was not caught because there was no proper testing. By
>> adding the missing tests, some implementations do indeed raise inexact
>> exceptions. 
> 
> There is testing that, in the terminology used by IEEE 754, the operations 
> do not raise the exception flag (the result of default exception handling 
> when the exception is signaled).  This is done through 
> NO_INEXACT_EXCEPTION in libm-test-*.inc.
> 
> What is not tested is specifically quality of implementation when 
> exception traps are enabled (a GNU extension outside the scope of the C 
> standard).

Ack, I will add that we are now testing for exception traps.

> 
> I think that as a user-visible fix, there should be a bug filed in 
> Bugzilla for this issue (that can then be marked FIXED so it goes in the 
> automatically generated list of bugs fixed in the next release).
> 

Alright, I open bug for the x86 issues.

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

* Re: [PATCH v2 00/10] Improve rounding to interger function for C23
  2024-04-03 17:10   ` Adhemerval Zanella Netto
@ 2024-04-04  5:25     ` Paul Zimmermann
  0 siblings, 0 replies; 21+ messages in thread
From: Paul Zimmermann @ 2024-04-04  5:25 UTC (permalink / raw)
  To: Adhemerval Zanella Netto; +Cc: josmyers, libc-alpha, hjl.tools

       Dear Adhemerval,

since nobody seems to have noticed, please fix the subject of this thread:
interger -> integer.

Paul

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

end of thread, other threads:[~2024-04-04  5:25 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-03 12:11 [PATCH v2 00/10] Improve rounding to interger function for C23 Adhemerval Zanella
2024-04-03 12:11 ` [PATCH v2 01/10] math: Add test to check if ceil raise inexact floating-point exception Adhemerval Zanella
2024-04-03 12:54   ` H.J. Lu
2024-04-03 12:11 ` [PATCH v2 02/10] math: Add test to check if floor " Adhemerval Zanella
2024-04-03 12:55   ` H.J. Lu
2024-04-03 12:11 ` [PATCH v2 03/10] math: Add test to check if trunc " Adhemerval Zanella
2024-04-03 12:55   ` H.J. Lu
2024-04-03 12:11 ` [PATCH v2 04/10] math: Add test to check if round " Adhemerval Zanella
2024-04-03 12:56   ` H.J. Lu
2024-04-03 12:11 ` [PATCH v2 05/10] x86: Do not raise inexact exception on ceill Adhemerval Zanella
2024-04-03 13:04   ` H.J. Lu
2024-04-03 13:15     ` Adhemerval Zanella Netto
2024-04-03 13:28       ` H.J. Lu
2024-04-03 12:11 ` [PATCH v2 06/10] x86: Do not raise inexact exception on floorl Adhemerval Zanella
2024-04-03 12:11 ` [PATCH v2 07/10] x86: Do not raise inexact exception on truncl Adhemerval Zanella
2024-04-03 12:11 ` [PATCH v2 08/10] x86: Do not raise inexact exception on floor/floorf Adhemerval Zanella
2024-04-03 12:11 ` [PATCH v2 09/10] i386: Do not raise inexact exception on ceil/ceilf Adhemerval Zanella
2024-04-03 12:11 ` [PATCH v2 10/10] i386: Do not raise inexact exception on trunc/truncf Adhemerval Zanella
2024-04-03 15:03 ` [PATCH v2 00/10] Improve rounding to interger function for C23 Joseph Myers
2024-04-03 17:10   ` Adhemerval Zanella Netto
2024-04-04  5:25     ` Paul Zimmermann

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