diff options
author | Jakub Jelinek <jakub@redhat.com> | 2020-04-22 19:17:15 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2020-04-22 21:34:19 +0200 |
commit | 1868599f8daf7798018ce8a8f314015f5a2ac520 (patch) | |
tree | 4a9e4d8e1017d6bc4c3f1de3eaff89af049d9c90 /libgfortran/intrinsics/c99_functions.c | |
parent | 545f1addf7247a800bbb943650efaa4c35d3bd1d (diff) | |
download | gcc-1868599f8daf7798018ce8a8f314015f5a2ac520.tar.gz |
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.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/libgfortran/intrinsics/c99_functions.c b/libgfortran/intrinsics/c99_functions.c index 3ec5aeb8e05..b75d1777c4c 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 |