From: FX <fxcoudert@gmail.com>
To: fortran@gcc.gnu.org
Cc: gcc-patches@gcc.gnu.org
Subject: [PATCH] Fortran 2018 rounding modes changes
Date: Wed, 31 Aug 2022 20:29:12 +0200 [thread overview]
Message-ID: <F217A954-CC5E-454F-96CE-10CAAA692AD5@gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 654 bytes --]
This adds new F2018 features, that are not really enabled (because their runtime support is optional).
1. Add the new IEEE_AWAY rounding mode. It is unsupported on all known targets, but could be supported by glibc and AIX as part of the C2x proposal. Testing for now is minimal, but once a target supports that rounding mode, the tests will fail and we can fix them by expanding them.
2. Add the optional RADIX argument to IEEE_SET_ROUNDING_MODE and IEEE_GET_ROUNDING_MODE. It is unused for now, because we do not support floating-point radices other than 2.
Regression-tested on x86_64-pc-linux-gnu, both 32- and 64-bit.
OK to commit?
[-- Attachment #2: 0001-fortran-Fortran-2018-rounding-modes-changes.patch --]
[-- Type: application/octet-stream, Size: 8346 bytes --]
From 06c1c3f53941c347205dd12bfe3c1601f829accb Mon Sep 17 00:00:00 2001
From: Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
Date: Wed, 31 Aug 2022 19:15:20 +0200
Subject: [PATCH] fortran: Fortran 2018 rounding modes changes
Add the new IEEE_AWAY rounding mode. It is unsupported on all known
targets, but could be supported by glibc and AIX as part of the C2x
proposal. Testing for now is minimal.
Add the optional RADIX argument to IEEE_SET_ROUNDING_MODE and
IEEE_GET_ROUNDING_MODE. It is unused for now, because we do not
support radices other than 2.
2022-08-31 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
gcc/fortran/
* libgfortran.h: Declare GFC_FPE_AWAY.
gcc/testsuite/
* gfortran.dg/ieee/rounding_2.f90: New test.
libgfortran/
* ieee/ieee_arithmetic.F90: Add RADIX argument to
IEEE_SET_ROUNDING_MODE and IEEE_GET_ROUNDING_MODE.
* config/fpu-387.h: Add IEEE_AWAY mode.
* config/fpu-aarch64.h: Add IEEE_AWAY mode.
* config/fpu-aix.h: Add IEEE_AWAY mode.
* config/fpu-generic.h: Add IEEE_AWAY mode.
* config/fpu-glibc.h: Add IEEE_AWAY mode.
* config/fpu-sysv.h: Add IEEE_AWAY mode.
---
gcc/fortran/libgfortran.h | 1 +
gcc/testsuite/gfortran.dg/ieee/rounding_2.f90 | 20 +++++++++++++++++
libgfortran/config/fpu-387.h | 7 ++++--
libgfortran/config/fpu-aarch64.h | 7 ++++--
libgfortran/config/fpu-aix.h | 22 +++++++++++++++++--
libgfortran/config/fpu-generic.h | 11 ++++++++--
libgfortran/config/fpu-glibc.h | 18 +++++++++++++++
libgfortran/config/fpu-sysv.h | 7 ++++--
libgfortran/ieee/ieee_arithmetic.F90 | 7 ++++--
9 files changed, 88 insertions(+), 12 deletions(-)
create mode 100644 gcc/testsuite/gfortran.dg/ieee/rounding_2.f90
diff --git a/gcc/fortran/libgfortran.h b/gcc/fortran/libgfortran.h
index ef06194eeb1..79a8c2ff450 100644
--- a/gcc/fortran/libgfortran.h
+++ b/gcc/fortran/libgfortran.h
@@ -60,6 +60,7 @@ along with GCC; see the file COPYING3. If not see
#define GFC_FPE_TONEAREST 2
#define GFC_FPE_TOWARDZERO 3
#define GFC_FPE_UPWARD 4
+#define GFC_FPE_AWAY 5
/* Size of the buffer required to store FPU state for any target.
In particular, this has to be larger than fenv_t on all glibc targets.
diff --git a/gcc/testsuite/gfortran.dg/ieee/rounding_2.f90 b/gcc/testsuite/gfortran.dg/ieee/rounding_2.f90
new file mode 100644
index 00000000000..8af6c9182f4
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/ieee/rounding_2.f90
@@ -0,0 +1,20 @@
+! { dg-do run }
+
+ use, intrinsic :: ieee_arithmetic
+ implicit none
+
+ real :: sx1, sx2, sx3
+ double precision :: dx1, dx2, dx3
+
+ ! IEEE_AWAY was added in Fortran 2018 and not supported by any target
+ ! at the moment. Just check we can query for its support.
+
+ ! We should support at least C float and C double types
+ if (ieee_support_rounding(ieee_away) &
+ .or. ieee_support_rounding(ieee_away, 0.) &
+ .or. ieee_support_rounding(ieee_away, 0.d0)) then
+ print *, "If a target / libc now supports this, we need to add a proper check!"
+ stop 1
+ end if
+
+end
diff --git a/libgfortran/config/fpu-387.h b/libgfortran/config/fpu-387.h
index fd00dab829a..e2f4a7d3fbf 100644
--- a/libgfortran/config/fpu-387.h
+++ b/libgfortran/config/fpu-387.h
@@ -418,9 +418,12 @@ get_fpu_rounding_mode (void)
}
int
-support_fpu_rounding_mode (int mode __attribute__((unused)))
+support_fpu_rounding_mode (int mode)
{
- return 1;
+ if (mode == GFC_FPE_AWAY)
+ return 0;
+ else
+ return 1;
}
void
diff --git a/libgfortran/config/fpu-aarch64.h b/libgfortran/config/fpu-aarch64.h
index 3a2e4bab8eb..47893908f60 100644
--- a/libgfortran/config/fpu-aarch64.h
+++ b/libgfortran/config/fpu-aarch64.h
@@ -293,9 +293,12 @@ set_fpu_rounding_mode (int round)
int
-support_fpu_rounding_mode (int mode __attribute__((unused)))
+support_fpu_rounding_mode (int mode)
{
- return 1;
+ if (mode == GFC_FPE_AWAY)
+ return 0;
+ else
+ return 1;
}
diff --git a/libgfortran/config/fpu-aix.h b/libgfortran/config/fpu-aix.h
index c643874af03..fb1ac809f03 100644
--- a/libgfortran/config/fpu-aix.h
+++ b/libgfortran/config/fpu-aix.h
@@ -320,6 +320,11 @@ get_fpu_rounding_mode (void)
return GFC_FPE_TOWARDZERO;
#endif
+#ifdef FE_TONEARESTFROMZERO
+ case FE_TONEARESTFROMZERO:
+ return GFC_FPE_AWAY;
+#endif
+
default:
return 0; /* Should be unreachable. */
}
@@ -357,8 +362,14 @@ set_fpu_rounding_mode (int mode)
break;
#endif
+#ifdef FE_TONEARESTFROMZERO
+ case GFC_FPE_AWAY:
+ rnd_mode = FE_TONEARESTFROMZERO;
+ break;
+#endif
+
default:
- return; /* Should be unreachable. */
+ return;
}
fesetround (rnd_mode);
@@ -398,8 +409,15 @@ support_fpu_rounding_mode (int mode)
return 0;
#endif
+ case GFC_FPE_AWAY:
+#ifdef FE_TONEARESTFROMZERO
+ return 1;
+#else
+ return 0;
+#endif
+
default:
- return 0; /* Should be unreachable. */
+ return 0;
}
}
diff --git a/libgfortran/config/fpu-generic.h b/libgfortran/config/fpu-generic.h
index 3b62228c1a1..9e976a8ded8 100644
--- a/libgfortran/config/fpu-generic.h
+++ b/libgfortran/config/fpu-generic.h
@@ -66,9 +66,16 @@ get_fpu_except_flags (void)
int
get_fpu_rounding_mode (void)
-{
+{
+ return 0;
+}
+
+
+int
+support_fpu_rounding_mode (int mode __attribute__((unused)))
+{
return 0;
-}
+}
void
diff --git a/libgfortran/config/fpu-glibc.h b/libgfortran/config/fpu-glibc.h
index 265ef693803..b56899fee0e 100644
--- a/libgfortran/config/fpu-glibc.h
+++ b/libgfortran/config/fpu-glibc.h
@@ -342,6 +342,11 @@ get_fpu_rounding_mode (void)
return GFC_FPE_TOWARDZERO;
#endif
+#ifdef FE_TONEARESTFROMZERO
+ case FE_TONEARESTFROMZERO:
+ return GFC_FPE_AWAY;
+#endif
+
default:
return 0; /* Should be unreachable. */
}
@@ -379,6 +384,12 @@ set_fpu_rounding_mode (int mode)
break;
#endif
+#ifdef FE_TONEARESTFROMZERO
+ case GFC_FPE_GFC_FPE_AWAY:
+ rnd_mode = FE_TONEARESTFROMZERO;
+ break;
+#endif
+
default:
return; /* Should be unreachable. */
}
@@ -420,6 +431,13 @@ support_fpu_rounding_mode (int mode)
return 0;
#endif
+ case GFC_FPE_AWAY:
+#ifdef FE_TONEARESTFROMZERO
+ return 1;
+#else
+ return 0;
+#endif
+
default:
return 0; /* Should be unreachable. */
}
diff --git a/libgfortran/config/fpu-sysv.h b/libgfortran/config/fpu-sysv.h
index 4de3852cea8..4681322ae9b 100644
--- a/libgfortran/config/fpu-sysv.h
+++ b/libgfortran/config/fpu-sysv.h
@@ -374,9 +374,12 @@ set_fpu_rounding_mode (int mode)
int
-support_fpu_rounding_mode (int mode __attribute__((unused)))
+support_fpu_rounding_mode (int mode)
{
- return 1;
+ if (mode == GFC_FPE_AWAY)
+ return 0;
+ else
+ return 1;
}
diff --git a/libgfortran/ieee/ieee_arithmetic.F90 b/libgfortran/ieee/ieee_arithmetic.F90
index 4e01aa5504c..7dce37a5099 100644
--- a/libgfortran/ieee/ieee_arithmetic.F90
+++ b/libgfortran/ieee/ieee_arithmetic.F90
@@ -73,6 +73,7 @@ module IEEE_ARITHMETIC
IEEE_TO_ZERO = IEEE_ROUND_TYPE(GFC_FPE_TOWARDZERO), &
IEEE_UP = IEEE_ROUND_TYPE(GFC_FPE_UPWARD), &
IEEE_DOWN = IEEE_ROUND_TYPE(GFC_FPE_DOWNWARD), &
+ IEEE_AWAY = IEEE_ROUND_TYPE(GFC_FPE_AWAY), &
IEEE_OTHER = IEEE_ROUND_TYPE(0)
@@ -1044,9 +1045,10 @@ contains
! IEEE_GET_ROUNDING_MODE
- subroutine IEEE_GET_ROUNDING_MODE (ROUND_VALUE)
+ subroutine IEEE_GET_ROUNDING_MODE (ROUND_VALUE, RADIX)
implicit none
type(IEEE_ROUND_TYPE), intent(out) :: ROUND_VALUE
+ integer, intent(in), optional :: RADIX
interface
integer function helper() &
@@ -1060,9 +1062,10 @@ contains
! IEEE_SET_ROUNDING_MODE
- subroutine IEEE_SET_ROUNDING_MODE (ROUND_VALUE)
+ subroutine IEEE_SET_ROUNDING_MODE (ROUND_VALUE, RADIX)
implicit none
type(IEEE_ROUND_TYPE), intent(in) :: ROUND_VALUE
+ integer, intent(in), optional :: RADIX
interface
subroutine helper(val) &
--
2.25.1
next reply other threads:[~2022-08-31 18:29 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-08-31 18:29 FX [this message]
2022-08-31 20:42 ` Bernhard Reutner-Fischer
2022-08-31 21:23 ` FX
2022-09-10 10:21 ` FX
2022-09-19 12:26 ` FX
2022-09-19 15:35 ` Mikael Morin
2022-09-19 16:17 ` FX
2022-09-19 17:09 ` Mikael Morin
2022-09-19 17:29 ` FX
2022-09-21 9:15 ` FX
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=F217A954-CC5E-454F-96CE-10CAAA692AD5@gmail.com \
--to=fxcoudert@gmail.com \
--cc=fortran@gcc.gnu.org \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).