From: Florian Weimer <fweimer@redhat.com>
To: GNU C Library <libc-alpha@sourceware.org>
Subject: math: Set 387 and SSE2 rounding mode for tgamma on i386 [BZ #23253]
Date: Wed, 20 Jun 2018 16:35:00 -0000 [thread overview]
Message-ID: <90429ec5-7b98-b9c4-cff0-69e788e3b2cf@redhat.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 223 bytes --]
This is my attempt at fixing a bunch of math test suite failures when
compiling with -mfpmath=sse on i686. I don't really know what I'm doing
here, but the whole thing looks internally consistent to me.
Thanks,
Florian
[-- Attachment #2: bug23253.patch --]
[-- Type: text/x-patch, Size: 7477 bytes --]
Subject: [PATCH] math: Set 387 and SSE2 rounding mode for tgamma on i386 [BZ #23253]
To: libc-alpha@sourceware.org
Previously, only the SSE2 rounding mode was set, so the assembler
implementations using 387 were not following the expecting rounding
mode.
2018-06-20 Florian Weimer <fweimer@redhat.com>
[BZ #23253]
* sysdeps/generic/math_private.h (default_libc_feholdsetround_ctx):
Renamed from libc_feholdsetround_ctx.
(default_libc_feresetround_ctx): Renamed from
libc_feresetround_ctx.
(default_libc_feholdsetround_noex_ctx): Renamed from
libc_feholdsetround_noex_ctx.
(default_libc_feresetround_noex_ctx): Renamed from
libc_feresetround_noex_ctx.
[!HAVE_RM_CTX] (libc_feholdsetround_ctx, libc_feresetround_ctx)
(libc_feholdsetround_noex_ctx, libc_feresetround_noex_ctx): Macros
forwardning to the old implementations under the new names.
* sysdeps/i386/fpu/fenv_private.h [__SSE_MATH__]
(libc_feholdexcept_setround_ctx, libc_fesetenv_ctx)
(libc_feupdateenv_ctx, libc_feholdsetround_ctx)
(libc_feresetround_ctx): Forward to default implements for i386
and MATH_SET_BOTH_ROUNDING_MODES.
* sysdeps/i386/Makefile [$(subdir) == math] (CFLAGS-e_gamma_r.c):
Add -DMATH_SET_BOTH_ROUNDING_MODES.
diff --git a/sysdeps/generic/math_private.h b/sysdeps/generic/math_private.h
index b6612ba6bf..1212abaf47 100644
--- a/sysdeps/generic/math_private.h
+++ b/sysdeps/generic/math_private.h
@@ -428,33 +428,6 @@ default_libc_feupdateenv_test (fenv_t *e, int ex)
# define HAVE_RM_CTX 0
#endif
-#if HAVE_RM_CTX
-/* Set/Restore Rounding Modes only when necessary. If defined, these functions
- set/restore floating point state only if the state needed within the lexical
- block is different from the current state. This saves a lot of time when
- the floating point unit is much slower than the fixed point units. */
-
-# ifndef libc_feholdsetround_noex_ctx
-# define libc_feholdsetround_noex_ctx libc_feholdsetround_ctx
-# endif
-# ifndef libc_feholdsetround_noexf_ctx
-# define libc_feholdsetround_noexf_ctx libc_feholdsetroundf_ctx
-# endif
-# ifndef libc_feholdsetround_noexl_ctx
-# define libc_feholdsetround_noexl_ctx libc_feholdsetroundl_ctx
-# endif
-
-# ifndef libc_feresetround_noex_ctx
-# define libc_feresetround_noex_ctx libc_fesetenv_ctx
-# endif
-# ifndef libc_feresetround_noexf_ctx
-# define libc_feresetround_noexf_ctx libc_fesetenvf_ctx
-# endif
-# ifndef libc_feresetround_noexl_ctx
-# define libc_feresetround_noexl_ctx libc_fesetenvl_ctx
-# endif
-
-#else
/* Default implementation using standard fenv functions.
Avoid unnecessary rounding mode changes by first checking the
@@ -462,7 +435,7 @@ default_libc_feupdateenv_test (fenv_t *e, int ex)
important for performance. */
static __always_inline void
-libc_feholdsetround_ctx (struct rm_ctx *ctx, int round)
+default_libc_feholdsetround_ctx (struct rm_ctx *ctx, int round)
{
ctx->updated_status = false;
@@ -476,7 +449,7 @@ libc_feholdsetround_ctx (struct rm_ctx *ctx, int round)
}
static __always_inline void
-libc_feresetround_ctx (struct rm_ctx *ctx)
+default_libc_feresetround_ctx (struct rm_ctx *ctx)
{
/* Restore the rounding mode if updated. */
if (__glibc_unlikely (ctx->updated_status))
@@ -484,7 +457,7 @@ libc_feresetround_ctx (struct rm_ctx *ctx)
}
static __always_inline void
-libc_feholdsetround_noex_ctx (struct rm_ctx *ctx, int round)
+default_libc_feholdsetround_noex_ctx (struct rm_ctx *ctx, int round)
{
/* Save exception flags and rounding mode, and disable exception
traps. */
@@ -496,12 +469,45 @@ libc_feholdsetround_noex_ctx (struct rm_ctx *ctx, int round)
}
static __always_inline void
-libc_feresetround_noex_ctx (struct rm_ctx *ctx)
+default_libc_feresetround_noex_ctx (struct rm_ctx *ctx)
{
/* Restore exception flags and rounding mode. */
__fesetenv (&ctx->env);
}
+#if HAVE_RM_CTX
+/* Set/Restore Rounding Modes only when necessary. If defined, these functions
+ set/restore floating point state only if the state needed within the lexical
+ block is different from the current state. This saves a lot of time when
+ the floating point unit is much slower than the fixed point units. */
+
+# ifndef libc_feholdsetround_noex_ctx
+# define libc_feholdsetround_noex_ctx libc_feholdsetround_ctx
+# endif
+# ifndef libc_feholdsetround_noexf_ctx
+# define libc_feholdsetround_noexf_ctx libc_feholdsetroundf_ctx
+# endif
+# ifndef libc_feholdsetround_noexl_ctx
+# define libc_feholdsetround_noexl_ctx libc_feholdsetroundl_ctx
+# endif
+
+# ifndef libc_feresetround_noex_ctx
+# define libc_feresetround_noex_ctx libc_fesetenv_ctx
+# endif
+# ifndef libc_feresetround_noexf_ctx
+# define libc_feresetround_noexf_ctx libc_fesetenvf_ctx
+# endif
+# ifndef libc_feresetround_noexl_ctx
+# define libc_feresetround_noexl_ctx libc_fesetenvl_ctx
+# endif
+
+#else
+
+# define libc_feholdsetround_ctx default_libc_feholdsetround_ctx
+# define libc_feresetround_ctx default_libc_feresetround_ctx
+# define libc_feholdsetround_noex_ctx default_libc_feholdsetround_noex_ctx
+# define libc_feresetround_noex_ctx default_libc_feresetround_noex_ctx
+
# define libc_feholdsetroundf_ctx libc_feholdsetround_ctx
# define libc_feholdsetroundl_ctx libc_feholdsetround_ctx
# define libc_feresetroundf_ctx libc_feresetround_ctx
diff --git a/sysdeps/i386/Makefile b/sysdeps/i386/Makefile
index 1682394e76..e9302726cf 100644
--- a/sysdeps/i386/Makefile
+++ b/sysdeps/i386/Makefile
@@ -5,6 +5,14 @@ asm-CPPFLAGS += -DGAS_SYNTAX
# The i386 `long double' is a distinct type we support.
long-double-fcts = yes
+ifeq ($(subdir),math)
+# These functions change the rounding mode internally and need to
+# update both the SSE2 rounding mod and the 387 rounding mode. See
+# the handling of MATH_SET_BOTH_ROUNDING_MODES in
+# sysdeps/i386/fpu/fenv_private.h.
+CFLAGS-e_gamma_r.c += -DMATH_SET_BOTH_ROUNDING_MODES
+endif
+
ifeq ($(subdir),string)
sysdep_routines += cacheinfo
endif
diff --git a/sysdeps/i386/fpu/fenv_private.h b/sysdeps/i386/fpu/fenv_private.h
index 59e83d858a..637dae5f05 100644
--- a/sysdeps/i386/fpu/fenv_private.h
+++ b/sysdeps/i386/fpu/fenv_private.h
@@ -460,11 +460,19 @@ libc_feupdateenv_387_ctx (struct rm_ctx *ctx)
#endif /* __SSE_MATH__ */
#ifdef __SSE2_MATH__
-# define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_sse_ctx
-# define libc_fesetenv_ctx libc_fesetenv_sse_ctx
-# define libc_feupdateenv_ctx libc_feupdateenv_sse_ctx
-# define libc_feholdsetround_ctx libc_feholdsetround_sse_ctx
-# define libc_feresetround_ctx libc_feresetround_sse_ctx
+# if defined (__x86_64__) || !defined (MATH_SET_BOTH_ROUNDING_MODES)
+# define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_sse_ctx
+# define libc_fesetenv_ctx libc_fesetenv_sse_ctx
+# define libc_feupdateenv_ctx libc_feupdateenv_sse_ctx
+# define libc_feholdsetround_ctx libc_feholdsetround_sse_ctx
+# define libc_feresetround_ctx libc_feresetround_sse_ctx
+# else
+# define libc_feholdexcept_setround_ctx default_libc_feholdexcept_setround_ctx
+# define libc_fesetenv_ctx default_libc_fesetenv_ctx
+# define libc_feupdateenv_ctx default_libc_feupdateenv_ctx
+# define libc_feholdsetround_ctx default_libc_feholdsetround_ctx
+# define libc_feresetround_ctx default_libc_feresetround_ctx
+# endif
#else
# define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_387_ctx
# define libc_feupdateenv_ctx libc_feupdateenv_387_ctx
next reply other threads:[~2018-06-20 16:35 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-20 16:35 Florian Weimer [this message]
2018-06-20 21:07 ` Joseph Myers
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=90429ec5-7b98-b9c4-cff0-69e788e3b2cf@redhat.com \
--to=fweimer@redhat.com \
--cc=libc-alpha@sourceware.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).