[v2,1/3] Cleanup __ieee754_sqrt(f/l)

Message ID DB6PR0801MB20536A8C78D2B93DE2412C7E830C0@DB6PR0801MB2053.eurprd08.prod.outlook.com
State New, archived
Headers

Commit Message

Wilco Dijkstra Dec. 20, 2017, 5:08 p.m. UTC
  Here is the updated version of the sqrt cleanup. Makefile magic is now fixed
to do a single selection at the top level (I couldn't add this to math-flags as
somehow that doesn't work properly).

This patch series cleans up the many uses of  __ieee754_sqrt(f/l) in GLIBC.
The goal is to enable GCC to do the inlining, and if this fails call the
__ieee754_sqrt function.  This is done by internally declaring sqrt with asm
redirects.  The compat symbols and sqrt wrappers need to disable the redirect.
The redirect is also disabled if there are already redirects defined when
using -ffinite-math-only.

All math functions (but not math tests) are built with -fno-math-errno which
means GCC will typically inline sqrt as a single instruction.

This means targets are no longer forced to add a special inline for sqrt.

Build & test OK on AArch64.

ChangeLog:
2017-12-20  Wilco Dijkstra  <wdijkstr@arm.com>

        * include/math.h (sqrt): Declare with asm redirect.
        (sqrtf): Likewise.
        (sqrtl): Likewise.
        * Makeconfig: Add -fno-math-errno for libc/libm, but build tests
        with -fmath-errno.
        * math/w_sqrt_compat.c: Define NO_SQRT_REDIRECT.
        * math/w_sqrt_template.c: Likewise.
        * math/w_sqrtf_compat.c: Likewise.
        * math/w_sqrtl_compat.c: Likewise.
--
  

Comments

Joseph Myers Dec. 20, 2017, 6:07 p.m. UTC | #1
On Wed, 20 Dec 2017, Wilco Dijkstra wrote:

> Build & test OK on AArch64.

I think the general design is right, but I also think this really needs a 
build-many-glibcs.py test run (as do subsequent patches moving calls to 
use sqrt/sqrtf/sqrtl directly) because of the high risk of 
architecture-specific breakage.

(Direct calling of sqrtf128 with similar redirects to those for sqrt / 
sqrtf / sqrtl is also appropriate: GCC 8 has it as a built-in function so 
can inline calls with -fno-math-errno on powerpc64le for POWER9.  So the 
patch should include a sqrtf128 redirect if __HAVE_DISTINCT_FLOAT128.)

> diff --git a/math/w_sqrt_template.c b/math/w_sqrt_template.c
> index 5fae302382d10e9b05df2665c9cb05126cd62f02..235c263e60c85422e41bca7c817148b66030438f 100644
> --- a/math/w_sqrt_template.c
> +++ b/math/w_sqrt_template.c
> @@ -21,6 +21,7 @@
>     for each floating-point type.  */
>  #if __USE_WRAPPER_TEMPLATE
>  
> +#define NO_SQRT_REDIRECT

Missing preprocessor indentation, "# define".
  

Patch

diff --git a/Makeconfig b/Makeconfig
index 34bed9790fac1fd0be9e16b7fe2fa6f5c479b32b..b9da1c137bc495a2f63064765225dc8878cde306 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -831,6 +831,9 @@  endif
 # disable any optimization that assume default rounding mode.
 +math-flags = -frounding-math
 
+# Build libc/libm using -fno-math-errno, but run testsuite with -fmath-errno.
++extra-math-flags = $(if $(filter nonlib testsuite,$(in-module)),-fmath-errno,-fno-math-errno)
+
 # We might want to compile with some stack-protection flag.
 ifneq ($(stack-protector),)
 +stack-protector=$(stack-protector)
@@ -966,6 +969,7 @@  endif
 
 override CFLAGS	= -std=gnu11 -fgnu89-inline $(config-extra-cflags) \
 		  $(filter-out %frame-pointer,$(+cflags)) $(+gccwarn-c) \
+		  $(+extra-math-flags) \
 		  $(sysdep-CFLAGS) $(CFLAGS-$(suffix $@)) $(CFLAGS-$(<F)) \
 		  $(CFLAGS-$(@F)) $(tls-model) \
 		  $(foreach lib,$(libof-$(basename $(@F))) \
diff --git a/include/math.h b/include/math.h
index 7ee291fc972088a1409949326f7024e8e3fe5415..f047308c4b1dc6099bcf56389649509b63b28996 100644
--- a/include/math.h
+++ b/include/math.h
@@ -54,5 +54,17 @@  libm_hidden_proto (__expf128)
 libm_hidden_proto (__expm1f128)
 # endif
 
+# if !(defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0)
+#  ifndef NO_SQRT_REDIRECT
+/* Declare sqrt for use within GLIBC.  Sqrt will typically inline into a
+   single instruction.  Use an asm to avoid use of PLTs if it doesn't.  */
+float (sqrtf) (float) asm ("__ieee754_sqrtf");
+double (sqrt) (double) asm ("__ieee754_sqrt");
+#   ifndef __NO_LONG_DOUBLE_MATH
+long double (sqrtl) (long double) asm ("__ieee754_sqrtl");
+#   endif
+#  endif
+# endif
+
 #endif
 #endif
diff --git a/math/w_sqrt_compat.c b/math/w_sqrt_compat.c
index 3280d2fbb86af2aeaf6e686fd38579b209c901aa..fe068af9597ffb0f15b32cd454b4c34ba8bc060e 100644
--- a/math/w_sqrt_compat.c
+++ b/math/w_sqrt_compat.c
@@ -16,6 +16,7 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define NO_SQRT_REDIRECT
 #include <math.h>
 #include <math_private.h>
 #include <math-svid-compat.h>
diff --git a/math/w_sqrt_template.c b/math/w_sqrt_template.c
index 5fae302382d10e9b05df2665c9cb05126cd62f02..235c263e60c85422e41bca7c817148b66030438f 100644
--- a/math/w_sqrt_template.c
+++ b/math/w_sqrt_template.c
@@ -21,6 +21,7 @@ 
    for each floating-point type.  */
 #if __USE_WRAPPER_TEMPLATE
 
+#define NO_SQRT_REDIRECT
 # include <errno.h>
 # include <fenv.h>
 # include <math.h>
diff --git a/math/w_sqrtf_compat.c b/math/w_sqrtf_compat.c
index 6c8c7e3857c7dacf52de6b575a2386095688b5dc..880be0936d9a20f9aa75cf2d66000f0c621f090f 100644
--- a/math/w_sqrtf_compat.c
+++ b/math/w_sqrtf_compat.c
@@ -16,6 +16,7 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define NO_SQRT_REDIRECT
 #include <math.h>
 #include <math_private.h>
 #include <math-svid-compat.h>
diff --git a/math/w_sqrtl_compat.c b/math/w_sqrtl_compat.c
index 0590f6d155fee27d41bfd42c1dbdf19c381ba1c8..bff77fd31bf2c62394e0d54e6b2e7bc9296226d6 100644
--- a/math/w_sqrtl_compat.c
+++ b/math/w_sqrtl_compat.c
@@ -16,6 +16,7 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define NO_SQRT_REDIRECT
 #include <math.h>
 #include <math_private.h>
 #include <math-svid-compat.h>