Use round functions not __round functions in glibc libm [committed]

Message ID alpine.DEB.2.21.1809271235440.15066@digraph.polyomino.org.uk
State Committed
Headers

Commit Message

Joseph Myers Sept. 27, 2018, 12:36 p.m. UTC
  Continuing the move to use, within libm, public names for libm
functions that can be inlined as built-in functions on many
architectures, this patch moves calls to __round functions to call the
corresponding round names instead, with asm redirection to __round
when the calls are not inlined.

An additional complication arises in
sysdeps/ieee754/ldbl-128ibm/e_expl.c, where a call to roundl, with the
result converted to int, gets converted by the compiler to call
lroundl in the case of 32-bit long, so resulting in localplt test
failures.  It's logically correct to let the compiler make such an
optimization; an appropriate asm redirection of lroundl to __lroundl
is thus added to that file (it's not needed anywhere else).

Tested for x86_64, and with build-many-glibcs.py.  Committed.

2018-09-27  Joseph Myers  <joseph@codesourcery.com>

	* include/math.h [!_ISOMAC && !(__FINITE_MATH_ONLY__ &&
	__FINITE_MATH_ONLY__ > 0) && !NO_MATH_REDIRECT] (round): Redirect
	using MATH_REDIRECT.
	* sysdeps/aarch64/fpu/s_round.c: Define NO_MATH_REDIRECT before
	header inclusion.
	* sysdeps/aarch64/fpu/s_roundf.c: Likewise.
	* sysdeps/ieee754/dbl-64/s_round.c: Likewise.
	* sysdeps/ieee754/dbl-64/wordsize-64/s_round.c: Likewise.
	* sysdeps/ieee754/float128/s_roundf128.c: Likewise.
	* sysdeps/ieee754/flt-32/s_roundf.c: Likewise.
	* sysdeps/ieee754/ldbl-128/s_roundl.c: Likewise.
	* sysdeps/ieee754/ldbl-96/s_roundl.c: Likewise.
	* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_round.c: Likewise.
	* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_roundf.c: Likewise.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_round.c: Likewise.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf.c: Likewise.
	* sysdeps/riscv/rv64/rvd/s_round.c: Likewise.
	* sysdeps/riscv/rvf/s_roundf.c: Likewise.
	* sysdeps/ieee754/ldbl-128ibm/s_roundl.c: Likewise.
	(round): Redirect to __round.
	(__roundl): Call round instead of __round.
	* sysdeps/powerpc/fpu/math_private.h [_ARCH_PWR5X] (__round):
	Remove macro.
	[_ARCH_PWR5X] (__roundf): Likewise.
	* sysdeps/ieee754/dbl-64/e_gamma_r.c (gamma_positive): Use round
	functions instead of __round variants.
	* sysdeps/ieee754/flt-32/e_gammaf_r.c (gammaf_positive): Likewise.
	* sysdeps/ieee754/ldbl-128/e_gammal_r.c (gammal_positive):
	Likewise.
	* sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c (gammal_positive):
	Likewise.
	* sysdeps/ieee754/ldbl-96/e_gammal_r.c (gammal_positive):
	Likewise.
	* sysdeps/x86/fpu/powl_helper.c (__powl_helper): Likewise.
	* sysdeps/ieee754/ldbl-128ibm/e_expl.c (lroundl): Redirect to
	__lroundl.
	(__ieee754_expl): Call roundl instead of __roundl.
  

Comments

Zack Weinberg Sept. 27, 2018, 12:56 p.m. UTC | #1
On Thu, Sep 27, 2018 at 8:37 AM Joseph Myers <joseph@codesourcery.com> wrote:
>
> Continuing the move to use, within libm, public names for libm
> functions that can be inlined as built-in functions on many
> architectures, this patch moves calls to __round functions to call the
> corresponding round names instead, with asm redirection to __round
> when the calls are not inlined.

No objection to the patch itself, but ...

> It's logically correct to let the compiler make such an
> optimization; an appropriate asm redirection of lroundl to __lroundl
> is thus added to that file (it's not needed anywhere else).

... wouldn't it be better to put this redirection in include/math.h
anyway, so that if it becomes needed in another place in the future,
we won't have to do anything special to enable it?

zw
  
Joseph Myers Sept. 27, 2018, 1:58 p.m. UTC | #2
On Thu, 27 Sep 2018, Zack Weinberg wrote:

> > It's logically correct to let the compiler make such an
> > optimization; an appropriate asm redirection of lroundl to __lroundl
> > is thus added to that file (it's not needed anywhere else).
> 
> ... wouldn't it be better to put this redirection in include/math.h
> anyway, so that if it becomes needed in another place in the future,
> we won't have to do anything special to enable it?

That would then also require NO_MATH_REDIRECT to be defined in lots of 
files defining lround functions.  Which is not necessarily a bad idea, but 
we don't seem to have anywhere else wanting to call lround functions from 
within libm and thus benefiting from inlining them, at present.
  

Patch

diff --git a/include/math.h b/include/math.h
index f8482afc44..ca9a1f0cd6 100644
--- a/include/math.h
+++ b/include/math.h
@@ -105,6 +105,7 @@  MATH_REDIRECT (ceil, "__", MATH_REDIRECT_UNARY_ARGS)
 MATH_REDIRECT (floor, "__", MATH_REDIRECT_UNARY_ARGS)
 MATH_REDIRECT (rint, "__", MATH_REDIRECT_UNARY_ARGS)
 MATH_REDIRECT (trunc, "__", MATH_REDIRECT_UNARY_ARGS)
+MATH_REDIRECT (round, "__", MATH_REDIRECT_UNARY_ARGS)
 #  endif
 # endif
 
diff --git a/sysdeps/aarch64/fpu/s_round.c b/sysdeps/aarch64/fpu/s_round.c
index 275b00f318..ae020d3afa 100644
--- a/sysdeps/aarch64/fpu/s_round.c
+++ b/sysdeps/aarch64/fpu/s_round.c
@@ -16,6 +16,7 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define NO_MATH_REDIRECT
 #include <math.h>
 #include <libm-alias-double.h>
 
diff --git a/sysdeps/aarch64/fpu/s_roundf.c b/sysdeps/aarch64/fpu/s_roundf.c
index 201ffc54db..f87609b207 100644
--- a/sysdeps/aarch64/fpu/s_roundf.c
+++ b/sysdeps/aarch64/fpu/s_roundf.c
@@ -16,6 +16,7 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define NO_MATH_REDIRECT
 #include <math.h>
 #include <libm-alias-float.h>
 
diff --git a/sysdeps/ieee754/dbl-64/e_gamma_r.c b/sysdeps/ieee754/dbl-64/e_gamma_r.c
index 2cfe6d640e..7707c062cb 100644
--- a/sysdeps/ieee754/dbl-64/e_gamma_r.c
+++ b/sysdeps/ieee754/dbl-64/e_gamma_r.c
@@ -88,7 +88,7 @@  gamma_positive (double x, int *exp2_adj)
 	 starting by computing pow (X_ADJ, X_ADJ) with a power of 2
 	 factored out.  */
       double exp_adj = -eps;
-      double x_adj_int = __round (x_adj);
+      double x_adj_int = round (x_adj);
       double x_adj_frac = x_adj - x_adj_int;
       int x_adj_log2;
       double x_adj_mant = __frexp (x_adj, &x_adj_log2);
diff --git a/sysdeps/ieee754/dbl-64/s_round.c b/sysdeps/ieee754/dbl-64/s_round.c
index fa9e83196e..012b6dc43d 100644
--- a/sysdeps/ieee754/dbl-64/s_round.c
+++ b/sysdeps/ieee754/dbl-64/s_round.c
@@ -17,6 +17,7 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define NO_MATH_REDIRECT
 #include <math.h>
 
 #include <math_private.h>
diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_round.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_round.c
index 3323621ce3..2dfd1ed3a9 100644
--- a/sysdeps/ieee754/dbl-64/wordsize-64/s_round.c
+++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_round.c
@@ -17,6 +17,7 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define NO_MATH_REDIRECT
 #include <math.h>
 
 #include <math_private.h>
diff --git a/sysdeps/ieee754/float128/s_roundf128.c b/sysdeps/ieee754/float128/s_roundf128.c
index 1eb36f2a5e..d9f6fa4754 100644
--- a/sysdeps/ieee754/float128/s_roundf128.c
+++ b/sysdeps/ieee754/float128/s_roundf128.c
@@ -1,2 +1,3 @@ 
+#define NO_MATH_REDIRECT
 #include <float128_private.h>
 #include "../ldbl-128/s_roundl.c"
diff --git a/sysdeps/ieee754/flt-32/e_gammaf_r.c b/sysdeps/ieee754/flt-32/e_gammaf_r.c
index 7d9a6cbac4..6a9e28a309 100644
--- a/sysdeps/ieee754/flt-32/e_gammaf_r.c
+++ b/sysdeps/ieee754/flt-32/e_gammaf_r.c
@@ -81,7 +81,7 @@  gammaf_positive (float x, int *exp2_adj)
 	 starting by computing pow (X_ADJ, X_ADJ) with a power of 2
 	 factored out.  */
       float exp_adj = -eps;
-      float x_adj_int = __roundf (x_adj);
+      float x_adj_int = roundf (x_adj);
       float x_adj_frac = x_adj - x_adj_int;
       int x_adj_log2;
       float x_adj_mant = __frexpf (x_adj, &x_adj_log2);
diff --git a/sysdeps/ieee754/flt-32/s_roundf.c b/sysdeps/ieee754/flt-32/s_roundf.c
index 7c95125d9c..a411de69aa 100644
--- a/sysdeps/ieee754/flt-32/s_roundf.c
+++ b/sysdeps/ieee754/flt-32/s_roundf.c
@@ -17,6 +17,7 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define NO_MATH_REDIRECT
 #include <math.h>
 
 #include <math_private.h>
diff --git a/sysdeps/ieee754/ldbl-128/e_gammal_r.c b/sysdeps/ieee754/ldbl-128/e_gammal_r.c
index 184798fb54..837395e1fd 100644
--- a/sysdeps/ieee754/ldbl-128/e_gammal_r.c
+++ b/sysdeps/ieee754/ldbl-128/e_gammal_r.c
@@ -96,7 +96,7 @@  gammal_positive (_Float128 x, int *exp2_adj)
 	 starting by computing pow (X_ADJ, X_ADJ) with a power of 2
 	 factored out.  */
       _Float128 exp_adj = -eps;
-      _Float128 x_adj_int = __roundl (x_adj);
+      _Float128 x_adj_int = roundl (x_adj);
       _Float128 x_adj_frac = x_adj - x_adj_int;
       int x_adj_log2;
       _Float128 x_adj_mant = __frexpl (x_adj, &x_adj_log2);
diff --git a/sysdeps/ieee754/ldbl-128/s_roundl.c b/sysdeps/ieee754/ldbl-128/s_roundl.c
index 22789cedf3..4f0184fcac 100644
--- a/sysdeps/ieee754/ldbl-128/s_roundl.c
+++ b/sysdeps/ieee754/ldbl-128/s_roundl.c
@@ -18,6 +18,7 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define NO_MATH_REDIRECT
 #include <math.h>
 
 #include <math_private.h>
diff --git a/sysdeps/ieee754/ldbl-128ibm/e_expl.c b/sysdeps/ieee754/ldbl-128ibm/e_expl.c
index a5024559dc..0c33d88010 100644
--- a/sysdeps/ieee754/ldbl-128ibm/e_expl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/e_expl.c
@@ -134,6 +134,11 @@  static const long double C[] = {
  1.98412698413981650382436541785404286E-04L,
 };
 
+/* Avoid local PLT entry use from (int) roundl (...) being converted
+   to a call to lroundl in the case of 32-bit long and roundl not
+   inlined.  */
+long int lroundl (long double) asm ("__lroundl");
+
 long double
 __ieee754_expl (long double x)
 {
@@ -149,15 +154,15 @@  __ieee754_expl (long double x)
 
       SET_RESTORE_ROUND (FE_TONEAREST);
 
-      n = __roundl (x*M_1_LN2);
+      n = roundl (x*M_1_LN2);
       x = x-n*M_LN2_0;
       xl = n*M_LN2_1;
 
-      tval1 = __roundl (x*TWO8);
+      tval1 = roundl (x*TWO8);
       x -= __expl_table[T_EXPL_ARG1+2*tval1];
       xl -= __expl_table[T_EXPL_ARG1+2*tval1+1];
 
-      tval2 = __roundl (x*TWO15);
+      tval2 = roundl (x*TWO15);
       x -= __expl_table[T_EXPL_ARG2+2*tval2];
       xl -= __expl_table[T_EXPL_ARG2+2*tval2+1];
 
diff --git a/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c b/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c
index 36801213d4..6361d35428 100644
--- a/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c
+++ b/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c
@@ -95,7 +95,7 @@  gammal_positive (long double x, int *exp2_adj)
 	 starting by computing pow (X_ADJ, X_ADJ) with a power of 2
 	 factored out.  */
       long double exp_adj = -eps;
-      long double x_adj_int = __roundl (x_adj);
+      long double x_adj_int = roundl (x_adj);
       long double x_adj_frac = x_adj - x_adj_int;
       int x_adj_log2;
       long double x_adj_mant = __frexpl (x_adj, &x_adj_log2);
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_roundl.c b/sysdeps/ieee754/ldbl-128ibm/s_roundl.c
index 94a62dcd6c..156be267a0 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_roundl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/s_roundl.c
@@ -20,12 +20,15 @@ 
 /* This has been coded in assembler because GCC makes such a mess of it
    when it's coded in C.  */
 
+#define NO_MATH_REDIRECT
 #include <math.h>
 #include <math_private.h>
 #include <math_ldbl_opt.h>
 #include <float.h>
 #include <ieee754.h>
 
+double round (double) asm ("__round");
+
 
 long double
 __roundl (long double x)
@@ -39,7 +42,7 @@  __roundl (long double x)
 			&& __builtin_isless (__builtin_fabs (xh),
 					     __builtin_inf ()), 1))
     {
-      hi = __round (xh);
+      hi = round (xh);
       if (hi != xh)
 	{
 	  /* The high part is not an integer; the low part only
@@ -62,7 +65,7 @@  __roundl (long double x)
       else
 	{
 	  /* The high part is a nonzero integer.  */
-	  lo = __round (xl);
+	  lo = round (xl);
 	  if (fabs (lo - xl) == 0.5)
 	    {
 	      if (xh > 0 && xl < 0)
diff --git a/sysdeps/ieee754/ldbl-96/e_gammal_r.c b/sysdeps/ieee754/ldbl-96/e_gammal_r.c
index b0970335b9..49428eba44 100644
--- a/sysdeps/ieee754/ldbl-96/e_gammal_r.c
+++ b/sysdeps/ieee754/ldbl-96/e_gammal_r.c
@@ -89,7 +89,7 @@  gammal_positive (long double x, int *exp2_adj)
 	 starting by computing pow (X_ADJ, X_ADJ) with a power of 2
 	 factored out.  */
       long double exp_adj = -eps;
-      long double x_adj_int = __roundl (x_adj);
+      long double x_adj_int = roundl (x_adj);
       long double x_adj_frac = x_adj - x_adj_int;
       int x_adj_log2;
       long double x_adj_mant = __frexpl (x_adj, &x_adj_log2);
diff --git a/sysdeps/ieee754/ldbl-96/s_roundl.c b/sysdeps/ieee754/ldbl-96/s_roundl.c
index c5c304cb2e..1eeed0195d 100644
--- a/sysdeps/ieee754/ldbl-96/s_roundl.c
+++ b/sysdeps/ieee754/ldbl-96/s_roundl.c
@@ -17,6 +17,7 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define NO_MATH_REDIRECT
 #include <math.h>
 
 #include <math_private.h>
diff --git a/sysdeps/powerpc/fpu/math_private.h b/sysdeps/powerpc/fpu/math_private.h
index 7f2acbb833..2ed56fa2ab 100644
--- a/sysdeps/powerpc/fpu/math_private.h
+++ b/sysdeps/powerpc/fpu/math_private.h
@@ -35,28 +35,4 @@  __ieee754_sqrtf128 (_Float128 __x)
 }
 #endif
 
-#if defined _ARCH_PWR5X
-
-# ifndef __round
-#  define __round(x)			\
-    ({ double __z;			\
-      __asm __volatile (		\
-	"	frin %0,%1\n"		\
-		: "=f" (__z)		\
-		: "f" (x));		\
-     __z; })
-# endif
-# ifndef __roundf
-#  define __roundf(x)			\
-    ({ float __z;			\
-     __asm __volatile (			\
-	"	frin %0,%1\n"		\
-	"	frsp %0,%0\n"		\
-		: "=f" (__z)		\
-		: "f" (x));		\
-     __z; })
-# endif
-
-#endif	/* defined _ARCH_PWR5X */
-
 #endif /* _PPC_MATH_PRIVATE_H_ */
diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_round.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_round.c
index 65e7801315..e5b27daf81 100644
--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_round.c
+++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_round.c
@@ -16,6 +16,7 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define NO_MATH_REDIRECT
 #include <math.h>
 #include <math_ldbl_opt.h>
 #include <shlib-compat.h>
diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_roundf.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_roundf.c
index 0d923a2ca6..659a989a70 100644
--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_roundf.c
+++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_roundf.c
@@ -16,6 +16,7 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define NO_MATH_REDIRECT
 #include <math.h>
 #include <math_ldbl_opt.h>
 #include <shlib-compat.h>
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_round.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_round.c
index bfa4d8119e..cd9291bf74 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_round.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_round.c
@@ -16,6 +16,7 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define NO_MATH_REDIRECT
 #include <math.h>
 #include <math_ldbl_opt.h>
 #include <shlib-compat.h>
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf.c
index 3d77156846..bd8b4a4cf9 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf.c
@@ -16,6 +16,7 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define NO_MATH_REDIRECT
 #include <math.h>
 #include <math_ldbl_opt.h>
 #include <shlib-compat.h>
diff --git a/sysdeps/riscv/rv64/rvd/s_round.c b/sysdeps/riscv/rv64/rvd/s_round.c
index b3e5bc4f0d..e375d4d062 100644
--- a/sysdeps/riscv/rv64/rvd/s_round.c
+++ b/sysdeps/riscv/rv64/rvd/s_round.c
@@ -16,6 +16,7 @@ 
    License along with the GNU C Library.  If not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define NO_MATH_REDIRECT
 #include <math.h>
 #include <math_private.h>
 #include <fenv_private.h>
diff --git a/sysdeps/riscv/rvf/s_roundf.c b/sysdeps/riscv/rvf/s_roundf.c
index 87839de3fb..685a8e3beb 100644
--- a/sysdeps/riscv/rvf/s_roundf.c
+++ b/sysdeps/riscv/rvf/s_roundf.c
@@ -16,6 +16,7 @@ 
    License along with the GNU C Library.  If not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define NO_MATH_REDIRECT
 #include <math.h>
 #include <math_private.h>
 #include <fenv_private.h>
diff --git a/sysdeps/x86/fpu/powl_helper.c b/sysdeps/x86/fpu/powl_helper.c
index 651eedd792..469fd0fb18 100644
--- a/sysdeps/x86/fpu/powl_helper.c
+++ b/sysdeps/x86/fpu/powl_helper.c
@@ -216,7 +216,7 @@  __powl_helper (long double x, long double y)
 
   /* Split the base-2 logarithm of the result into integer and
      fractional parts.  */
-  long double log2_res_int = __roundl (log2_res_hi);
+  long double log2_res_int = roundl (log2_res_hi);
   long double log2_res_frac = log2_res_hi - log2_res_int + log2_res_lo;
   /* If the integer part is very large, the computed fractional part
      may be outside the valid range for f2xm1.  */