diff mbox series

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

Message ID alpine.DEB.2.21.1809271235440.15066@digraph.polyomino.org.uk
State New
Headers show
Series Use round functions not __round functions in glibc libm [committed] | expand

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.
diff mbox series

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.  */