public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Marius Hillenbrand <mhillen@linux.ibm.com>
To: Andreas Krebbel <krebbel@linux.ibm.com>
Cc: gcc-patches@gcc.gnu.org, Marius Hillenbrand <mhillen@linux.ibm.com>
Subject: [PATCH 1/2] IBM Z: Configure excess precision for float at compile-time
Date: Wed, 25 Nov 2020 18:06:23 +0100	[thread overview]
Message-ID: <20201125170622.5032-2-mhillen@linux.ibm.com> (raw)
In-Reply-To: <20201125170622.5032-1-mhillen@linux.ibm.com>

Historically, float_t has been defined as double on s390 and gcc would
emit double precision insns for evaluating float expressions when in
standard-compliant mode. Configure that behavior at compile-time as prep
for changes in glibc: When glibc ties float_t to double, keep the old
behavior; when glibc derives float_t from FLT_EVAL_METHOD (as on most
other archs), revert to the default behavior (i.e.,
FLT_EVAL_METHOD_PROMOTE_TO_FLOAT). Provide a configure option
--enable-s390-excess-float-precision to override the check.

gcc/ChangeLog:

2020-11-25  Marius Hillenbrand  <mhillen@linux.ibm.com>

	* configure.ac: Add configure option
	--enable-s390-excess-float-precision and check to derive default
	from glibc.
	* config/s390/s390.c: Guard s390_excess_precision with an ifdef
	for ENABLE_S390_EXCESS_FLOAT_PRECISION.
	* doc/install.texi: Document --enable-s390-excess-float-precision.
	* configure: Regenerate.
	* config.in: Regenerate.
---
 gcc/config/s390/s390.c | 27 ++++++++++++++++++-------
 gcc/configure.ac       | 45 ++++++++++++++++++++++++++++++++++++++++++
 gcc/doc/install.texi   | 10 ++++++++++
 3 files changed, 75 insertions(+), 7 deletions(-)

diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 6983e363252..02f18366aa1 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -16376,20 +16376,28 @@ s390_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1, const_tree ty
   return NULL;
 }
 
-/* Implement TARGET_C_EXCESS_PRECISION.
+#if ENABLE_S390_EXCESS_FLOAT_PRECISION == 1
+/* Implement TARGET_C_EXCESS_PRECISION to maintain historic behavior with older
+   glibc versions
 
-   FIXME: For historical reasons, float_t and double_t are typedef'ed to
+   For historical reasons, float_t and double_t had been typedef'ed to
    double on s390, causing operations on float_t to operate in a higher
    precision than is necessary.  However, it is not the case that SFmode
    operations have implicit excess precision, and we generate more optimal
    code if we let the compiler know no implicit extra precision is added.
 
-   That means when we are compiling with -fexcess-precision=fast, the value
-   we set for FLT_EVAL_METHOD will be out of line with the actual precision of
-   float_t (though they would be correct for -fexcess-precision=standard).
+   With a glibc with that "historic" definition, configure will enable this hook
+   to set FLT_EVAL_METHOD to 1 for -fexcess-precision=standard (e.g., as implied
+   by -std=cXY).  That means when we are compiling with -fexcess-precision=fast,
+   the value we set for FLT_EVAL_METHOD will be out of line with the actual
+   precision of float_t.
 
-   A complete fix would modify glibc to remove the unnecessary typedef
-   of float_t to double.  */
+   Newer versions of glibc will be modified to derive the definition of float_t
+   from FLT_EVAL_METHOD on s390x, as on many other architectures.  There,
+   configure will disable this hook by default, so that we defer to the default
+   of FLT_EVAL_METHOD_PROMOTE_TO_FLOAT and a resulting typedef of float_t to
+   float.  Note that in that scenario, float_t and FLT_EVAL_METHOD will be in
+   line independent of -fexcess-precision. */
 
 static enum flt_eval_method
 s390_excess_precision (enum excess_precision_type type)
@@ -16412,6 +16420,7 @@ s390_excess_precision (enum excess_precision_type type)
     }
   return FLT_EVAL_METHOD_UNPREDICTABLE;
 }
+#endif
 
 /* Implement the TARGET_ASAN_SHADOW_OFFSET hook.  */
 
@@ -16708,8 +16717,12 @@ s390_shift_truncation_mask (machine_mode mode)
 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
 
+#if ENABLE_S390_EXCESS_FLOAT_PRECISION == 1
+/* This hook is only needed to maintain the historic behavior with glibc
+   versions that typedef float_t to double. */
 #undef TARGET_C_EXCESS_PRECISION
 #define TARGET_C_EXCESS_PRECISION s390_excess_precision
+#endif
 
 #undef  TARGET_SCHED_ADJUST_PRIORITY
 #define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
diff --git a/gcc/configure.ac b/gcc/configure.ac
index b410428b4fc..24679a540c1 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -7318,6 +7318,51 @@ if test x"$ld_pushpopstate_support" = xyes; then
 fi
 AC_MSG_RESULT($ld_pushpopstate_support)
 
+# On s390, float_t has historically been statically defined as double for no
+# good reason. To comply with the C standard in the light of this definition,
+# gcc has evaluated float expressions in double precision when in
+# standards-compatible mode or when given -fexcess-precision=standard. To enable
+# a smooth transition towards the new model used by most architectures, where
+# gcc describes its behavior via the macro __FLT_EVAL_METHOD__ and glibc derives
+# float_t from that, this behavior can be configured with
+# --enable-s390-excess-float-precision. When given as enabled, that flag selects
+# the old model. When omitted, native builds will derive the flag from the
+# behavior of glibc. When glibc clamps float_t to double, gcc follows the old
+# model. In any other case, it defaults to the new model.
+AC_ARG_ENABLE(s390-excess-float-precision,
+  [AS_HELP_STRING([--enable-s390-excess-float-precision],
+		  [on s390 targets, evaluate float with double precision
+		   when in standards-conforming mode])],
+  [],[enable_s390_excess_float_precision=auto])
+
+case $target in
+  s390*-linux*)
+  if test "$target" = "$host" -a "$host" = "$build" -a \
+      x"$enable_s390_excess_float_precision" = xauto; then
+    AC_CACHE_CHECK([for glibc clamping float_t to double],
+      gcc_cv_float_t_clamped_to_double,
+      [AC_RUN_IFELSE([AC_LANG_SOURCE([
+#define __FLT_EVAL_METHOD__ 0
+#include <math.h>
+int main() {
+  return !(sizeof(float_t) == sizeof(double));
+}])],
+        [gcc_cv_float_t_clamped_to_double=yes],
+        [gcc_cv_float_t_clamped_to_double=no])])
+    if test x"$gcc_cv_float_t_clamped_to_double" = xyes; then
+      enable_s390_excess_float_precision=yes
+    fi
+  fi
+
+  GCC_TARGET_TEMPLATE(ENABLE_S390_EXCESS_FLOAT_PRECISION)
+  if test x"$enable_s390_excess_float_precision" = xyes; then
+    AC_DEFINE(ENABLE_S390_EXCESS_FLOAT_PRECISION, 1,
+[Define to enable evaluating float expressions with double precision in
+standards-compatible mode on s390 targets.])
+  fi
+  ;;
+esac
+
 # Configure the subdirectories
 # AC_CONFIG_SUBDIRS($subdirs)
 
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 8c55da373f8..546f79d2b8e 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -2271,6 +2271,16 @@ information in object.
 
 The option is disabled by default. It is enabled on RISC-V/ELF (bare-metal)
 target if target binutils supported.
+
+@item --enable-s390-excess-float-precision
+@itemx --disable-s390-excess-float-precision
+On s390(x) targets, enable treatment of float expressions with double precision
+when in standards-compliant mode (e.g., when @code{--std=c99} or
+@code{-fexcess-precision=standard} are given).
+
+For a native build, the option's default is derived from glibc's behavior. When
+glibc clamps float_t to double, gcc follows and enables the option. In all other
+cases, it defaults to off.
 @end table
 
 @subheading Cross-Compiler-Specific Options
-- 
2.26.2


  reply	other threads:[~2020-11-25 17:07 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-25 17:06 [PATCH 0/2] IBM Z: Prepare cleanup of float express precision Marius Hillenbrand
2020-11-25 17:06 ` Marius Hillenbrand [this message]
2020-12-01 10:30   ` [PATCH 1/2] IBM Z: Configure excess precision for float at compile-time Andreas Krebbel
2020-11-25 17:06 ` [PATCH 2/2] gcc/testsuite/s390: Add test cases for float_t Marius Hillenbrand
2020-12-01 10:30   ` Andreas Krebbel

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=20201125170622.5032-2-mhillen@linux.ibm.com \
    --to=mhillen@linux.ibm.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=krebbel@linux.ibm.com \
    /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).