aboutsummaryrefslogtreecommitdiff
path: root/libgfortran/intrinsics/c99_functions.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-04-22 19:17:15 +0200
committerJakub Jelinek <jakub@redhat.com>2020-04-22 21:34:19 +0200
commit1868599f8daf7798018ce8a8f314015f5a2ac520 (patch)
tree4a9e4d8e1017d6bc4c3f1de3eaff89af049d9c90 /libgfortran/intrinsics/c99_functions.c
parent545f1addf7247a800bbb943650efaa4c35d3bd1d (diff)
downloadgcc-1868599f8daf7798018ce8a8f314015f5a2ac520.zip
gcc-1868599f8daf7798018ce8a8f314015f5a2ac520.tar.gz
gcc-1868599f8daf7798018ce8a8f314015f5a2ac520.tar.bz2
libgfortran: Provide some further math library fallbacks [PR94694]
The following patch provides some further math library fallbacks. fmaf can be implemented using fma if available, fma and fmal can use x * y + z as fallback, it is not perfect, but e.g. glibc on various arches has been using that as fallback for many years, and copysign/copysignl/fabs/fabsl can be implemented using corresponding __builtin_* if we make sure that gcc expands it inline instead of using a library call (these days it is expanded inline on most targets). 2020-04-22 Jakub Jelinek <jakub@redhat.com> PR libfortran/94694 PR libfortran/94586 * configure.ac: Add math func checks for fmaf, fma and fmal. Add HAVE_INLINE_BUILTIN_COPYSIGN check. * c99_protos.h (copysign, fmaf, fma, fmal): Provide fallback prototypes. (HAVE_COPYSIGN, HAVE_FMAF, HAVE_FMA, HAVE_FMAL): Define if not defined and fallback version is provided. * intrinsics/c99_functions.c (copysign, fmaf, fma, fmal): Provide fallback implementations if possible * configure: Regenerated. * config.h.in: Regenerated. * math.m4 (GCC_CHECK_MATH_INLINE_BUILTIN_FALLBACK1, GCC_CHECK_MATH_INLINE_BUILTIN_FALLBACK2): New.
Diffstat (limited to 'libgfortran/intrinsics/c99_functions.c')
-rw-r--r--libgfortran/intrinsics/c99_functions.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/libgfortran/intrinsics/c99_functions.c b/libgfortran/intrinsics/c99_functions.c
index 3ec5aeb..b75d177 100644
--- a/libgfortran/intrinsics/c99_functions.c
+++ b/libgfortran/intrinsics/c99_functions.c
@@ -229,6 +229,17 @@ ceilf (float x)
}
#endif
+#if !defined(HAVE_COPYSIGN) && defined(HAVE_INLINE_BUILTIN_COPYSIGN)
+#define HAVE_COPYSIGN 1
+double copysign (double x, double y);
+
+double
+copysign (double x, double y)
+{
+ return __builtin_copysign (x, y);
+}
+#endif
+
#ifndef HAVE_COPYSIGNF
#define HAVE_COPYSIGNF 1
float copysignf (float x, float y);
@@ -240,6 +251,17 @@ copysignf (float x, float y)
}
#endif
+#if !defined(HAVE_COPYSIGNL) && defined(HAVE_INLINE_BUILTIN_COPYSIGNL)
+#define HAVE_COPYSIGNL 1
+long double copysignl (long double x, long double y);
+
+long double
+copysignl (long double x, long double y)
+{
+ return __builtin_copysignl (x, y);
+}
+#endif
+
#ifndef HAVE_COSF
#define HAVE_COSF 1
float cosf (float x);
@@ -273,6 +295,17 @@ expf (float x)
}
#endif
+#if !defined(HAVE_FABS) && defined(HAVE_INLINE_BUILTIN_FABS)
+#define HAVE_FABS 1
+double fabs (double x);
+
+double
+fabs (double x)
+{
+ return __builtin_fabs (x);
+}
+#endif
+
#ifndef HAVE_FABSF
#define HAVE_FABSF 1
float fabsf (float x);
@@ -284,6 +317,17 @@ fabsf (float x)
}
#endif
+#if !defined(HAVE_FABSL) && defined(HAVE_INLINE_BUILTIN_FABSL)
+#define HAVE_FABSL 1
+long double fabsl (long double x);
+
+long double
+fabsl (long double x)
+{
+ return __builtin_fabsl (x);
+}
+#endif
+
#ifndef HAVE_FLOORF
#define HAVE_FLOORF 1
float floorf (float x);
@@ -2112,3 +2156,36 @@ lgammaf (float x)
return (float) lgamma ((double) x);
}
#endif
+
+#ifndef HAVE_FMA
+#define HAVE_FMA 1
+double fma (double, double, double);
+
+double
+fma (double x, double y, double z)
+{
+ return x * y + z;
+}
+#endif
+
+#ifndef HAVE_FMAF
+#define HAVE_FMAF 1
+float fmaf (float, float, float);
+
+float
+fmaf (float x, float y, float z)
+{
+ return fma (x, y, z);
+}
+#endif
+
+#ifndef HAVE_FMAL
+#define HAVE_FMAL 1
+long double fmal (long double, long double, long double);
+
+long double
+fmal (long double x, long double y, long double z)
+{
+ return x * y + z;
+}
+#endif