Fix cexpl when compiled with latest GCC

Message ID 201707202301.v6KN1uY2012836@sellcey-dt.caveonetworks.com
State New, archived
Headers

Commit Message

Steve Ellcey July 20, 2017, 11:01 p.m. UTC
  While testing glibc on aarch64 and building with the latest GCC (Top-of-tree)
I got several failures involving the long double exp function.   (See
https://sourceware.org/ml/libc-alpha/2017-07/msg00704.html)  The underflow
exception was getting raised where it should not be.

GCC does not know that moving floating point operations around the fesetenv
call can change the flag settings and glibc deals with this by using the
math_force_eval and math_opt_barrier macros to restrict GCC optimizations.

This patch adds a call to math_force_eval so that the multiplication that
creates x22 is completed before the fesetenv call and thus the underflow
exception that is generated by the expression does not get raised (it is
wiped out by the call to fesetenv).  That is the behavour that we want and
what glibc is doing when compiled with older compilers.

OK to checkin?  Is this something we want in for 2.26 or should it wait
until after the release?

Steve Ellcey
sellcey@cavium.com


2017-07-20  Steve Ellcey  <sellcey@cavium.com>

	* sysdeps/ieee754/ldbl-128/e_expl.c (__ieee754_expl): Call
	math_force_eval.
  

Comments

Siddhesh Poyarekar July 21, 2017, 4:11 a.m. UTC | #1
On Friday 21 July 2017 04:31 AM, Steve Ellcey wrote:
> While testing glibc on aarch64 and building with the latest GCC (Top-of-tree)
> I got several failures involving the long double exp function.   (See
> https://sourceware.org/ml/libc-alpha/2017-07/msg00704.html)  The underflow
> exception was getting raised where it should not be.
> 
> GCC does not know that moving floating point operations around the fesetenv
> call can change the flag settings and glibc deals with this by using the
> math_force_eval and math_opt_barrier macros to restrict GCC optimizations.
> 
> This patch adds a call to math_force_eval so that the multiplication that
> creates x22 is completed before the fesetenv call and thus the underflow
> exception that is generated by the expression does not get raised (it is
> wiped out by the call to fesetenv).  That is the behavour that we want and
> what glibc is doing when compiled with older compilers.
> 
> OK to checkin?  Is this something we want in for 2.26 or should it wait
> until after the release?

This is fine for 2.26.

Siddhesh

> Steve Ellcey
> sellcey@cavium.com
> 
> 
> 2017-07-20  Steve Ellcey  <sellcey@cavium.com>
> 
> 	* sysdeps/ieee754/ldbl-128/e_expl.c (__ieee754_expl): Call
> 	math_force_eval.
> 
> 
> diff --git a/sysdeps/ieee754/ldbl-128/e_expl.c b/sysdeps/ieee754/ldbl-128/e_expl.c
> index 15639d1..fd7700c 100644
> --- a/sysdeps/ieee754/ldbl-128/e_expl.c
> +++ b/sysdeps/ieee754/ldbl-128/e_expl.c
> @@ -192,6 +192,7 @@ __ieee754_expl (_Float128 x)
>  	 with maximum error in [-2^-16-2^-53,2^-16+2^-53]
>  	 less than 4.8e-39.  */
>        x22 = x + x*x*(P1+x*(P2+x*(P3+x*(P4+x*(P5+x*P6)))));
> +      math_force_eval (x22);
>  
>        /* Return result.  */
>        fesetenv (&oldenv);
>
  

Patch

diff --git a/sysdeps/ieee754/ldbl-128/e_expl.c b/sysdeps/ieee754/ldbl-128/e_expl.c
index 15639d1..fd7700c 100644
--- a/sysdeps/ieee754/ldbl-128/e_expl.c
+++ b/sysdeps/ieee754/ldbl-128/e_expl.c
@@ -192,6 +192,7 @@  __ieee754_expl (_Float128 x)
 	 with maximum error in [-2^-16-2^-53,2^-16+2^-53]
 	 less than 4.8e-39.  */
       x22 = x + x*x*(P1+x*(P2+x*(P3+x*(P4+x*(P5+x*P6)))));
+      math_force_eval (x22);
 
       /* Return result.  */
       fesetenv (&oldenv);