From patchwork Wed Jun 20 16:35:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 27948 Received: (qmail 98807 invoked by alias); 20 Jun 2018 16:35:21 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 98712 invoked by uid 89); 20 Jun 2018 16:35:20 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-23.8 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=4497 X-HELO: mx1.redhat.com To: GNU C Library From: Florian Weimer Subject: math: Set 387 and SSE2 rounding mode for tgamma on i386 [BZ #23253] Message-ID: <90429ec5-7b98-b9c4-cff0-69e788e3b2cf@redhat.com> Date: Wed, 20 Jun 2018 18:35:13 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.8.0 MIME-Version: 1.0 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 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 [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