diff options
50 files changed, 5647 insertions, 1 deletions
diff --git a/bits/libm-simd-decl-stubs.h b/bits/libm-simd-decl-stubs.h index 33d480031b..21f1a43232 100644 --- a/bits/libm-simd-decl-stubs.h +++ b/bits/libm-simd-decl-stubs.h @@ -285,4 +285,15 @@ #define __DECL_SIMD_erff32x #define __DECL_SIMD_erff64x #define __DECL_SIMD_erff128x + +#define __DECL_SIMD_tanh +#define __DECL_SIMD_tanhf +#define __DECL_SIMD_tanhl +#define __DECL_SIMD_tanhf16 +#define __DECL_SIMD_tanhf32 +#define __DECL_SIMD_tanhf64 +#define __DECL_SIMD_tanhf128 +#define __DECL_SIMD_tanhf32x +#define __DECL_SIMD_tanhf64x +#define __DECL_SIMD_tanhf128x #endif diff --git a/math/bits/mathcalls.h b/math/bits/mathcalls.h index a5b6c4457f..3d1c2056d5 100644 --- a/math/bits/mathcalls.h +++ b/math/bits/mathcalls.h @@ -72,7 +72,7 @@ __MATHCALL_VEC (cosh,, (_Mdouble_ __x)); /* Hyperbolic sine of X. */ __MATHCALL_VEC (sinh,, (_Mdouble_ __x)); /* Hyperbolic tangent of X. */ -__MATHCALL (tanh,, (_Mdouble_ __x)); +__MATHCALL_VEC (tanh,, (_Mdouble_ __x)); #ifdef __USE_GNU /* Cosine and sine of X. */ diff --git a/sysdeps/unix/sysv/linux/x86_64/libmvec.abilist b/sysdeps/unix/sysv/linux/x86_64/libmvec.abilist index 5525c8a0d6..e178cef683 100644 --- a/sysdeps/unix/sysv/linux/x86_64/libmvec.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/libmvec.abilist @@ -61,6 +61,7 @@ GLIBC_2.35 _ZGVbN2v_log10 F GLIBC_2.35 _ZGVbN2v_log1p F GLIBC_2.35 _ZGVbN2v_log2 F GLIBC_2.35 _ZGVbN2v_sinh F +GLIBC_2.35 _ZGVbN2v_tanh F GLIBC_2.35 _ZGVbN2vv_atan2 F GLIBC_2.35 _ZGVbN2vv_hypot F GLIBC_2.35 _ZGVbN4v_acosf F @@ -78,6 +79,7 @@ GLIBC_2.35 _ZGVbN4v_log10f F GLIBC_2.35 _ZGVbN4v_log1pf F GLIBC_2.35 _ZGVbN4v_log2f F GLIBC_2.35 _ZGVbN4v_sinhf F +GLIBC_2.35 _ZGVbN4v_tanhf F GLIBC_2.35 _ZGVbN4vv_atan2f F GLIBC_2.35 _ZGVbN4vv_hypotf F GLIBC_2.35 _ZGVcN4v_acos F @@ -95,6 +97,7 @@ GLIBC_2.35 _ZGVcN4v_log10 F GLIBC_2.35 _ZGVcN4v_log1p F GLIBC_2.35 _ZGVcN4v_log2 F GLIBC_2.35 _ZGVcN4v_sinh F +GLIBC_2.35 _ZGVcN4v_tanh F GLIBC_2.35 _ZGVcN4vv_atan2 F GLIBC_2.35 _ZGVcN4vv_hypot F GLIBC_2.35 _ZGVcN8v_acosf F @@ -112,6 +115,7 @@ GLIBC_2.35 _ZGVcN8v_log10f F GLIBC_2.35 _ZGVcN8v_log1pf F GLIBC_2.35 _ZGVcN8v_log2f F GLIBC_2.35 _ZGVcN8v_sinhf F +GLIBC_2.35 _ZGVcN8v_tanhf F GLIBC_2.35 _ZGVcN8vv_atan2f F GLIBC_2.35 _ZGVcN8vv_hypotf F GLIBC_2.35 _ZGVdN4v_acos F @@ -129,6 +133,7 @@ GLIBC_2.35 _ZGVdN4v_log10 F GLIBC_2.35 _ZGVdN4v_log1p F GLIBC_2.35 _ZGVdN4v_log2 F GLIBC_2.35 _ZGVdN4v_sinh F +GLIBC_2.35 _ZGVdN4v_tanh F GLIBC_2.35 _ZGVdN4vv_atan2 F GLIBC_2.35 _ZGVdN4vv_hypot F GLIBC_2.35 _ZGVdN8v_acosf F @@ -146,6 +151,7 @@ GLIBC_2.35 _ZGVdN8v_log10f F GLIBC_2.35 _ZGVdN8v_log1pf F GLIBC_2.35 _ZGVdN8v_log2f F GLIBC_2.35 _ZGVdN8v_sinhf F +GLIBC_2.35 _ZGVdN8v_tanhf F GLIBC_2.35 _ZGVdN8vv_atan2f F GLIBC_2.35 _ZGVdN8vv_hypotf F GLIBC_2.35 _ZGVeN16v_acosf F @@ -163,6 +169,7 @@ GLIBC_2.35 _ZGVeN16v_log10f F GLIBC_2.35 _ZGVeN16v_log1pf F GLIBC_2.35 _ZGVeN16v_log2f F GLIBC_2.35 _ZGVeN16v_sinhf F +GLIBC_2.35 _ZGVeN16v_tanhf F GLIBC_2.35 _ZGVeN16vv_atan2f F GLIBC_2.35 _ZGVeN16vv_hypotf F GLIBC_2.35 _ZGVeN8v_acos F @@ -180,5 +187,6 @@ GLIBC_2.35 _ZGVeN8v_log10 F GLIBC_2.35 _ZGVeN8v_log1p F GLIBC_2.35 _ZGVeN8v_log2 F GLIBC_2.35 _ZGVeN8v_sinh F +GLIBC_2.35 _ZGVeN8v_tanh F GLIBC_2.35 _ZGVeN8vv_atan2 F GLIBC_2.35 _ZGVeN8vv_hypot F diff --git a/sysdeps/x86/fpu/bits/math-vector.h b/sysdeps/x86/fpu/bits/math-vector.h index ea0deb31c1..3c657f6108 100644 --- a/sysdeps/x86/fpu/bits/math-vector.h +++ b/sysdeps/x86/fpu/bits/math-vector.h @@ -126,6 +126,10 @@ # define __DECL_SIMD_erf __DECL_SIMD_x86_64 # undef __DECL_SIMD_erff # define __DECL_SIMD_erff __DECL_SIMD_x86_64 +# undef __DECL_SIMD_tanh +# define __DECL_SIMD_tanh __DECL_SIMD_x86_64 +# undef __DECL_SIMD_tanhf +# define __DECL_SIMD_tanhf __DECL_SIMD_x86_64 # endif #endif diff --git a/sysdeps/x86/fpu/finclude/math-vector-fortran.h b/sysdeps/x86/fpu/finclude/math-vector-fortran.h index 42addd9a25..c7f81945fe 100644 --- a/sysdeps/x86/fpu/finclude/math-vector-fortran.h +++ b/sysdeps/x86/fpu/finclude/math-vector-fortran.h @@ -62,6 +62,8 @@ !GCC$ builtin (acoshf) attributes simd (notinbranch) if('x86_64') !GCC$ builtin (erf) attributes simd (notinbranch) if('x86_64') !GCC$ builtin (erff) attributes simd (notinbranch) if('x86_64') +!GCC$ builtin (tanh) attributes simd (notinbranch) if('x86_64') +!GCC$ builtin (tanhf) attributes simd (notinbranch) if('x86_64') !GCC$ builtin (cos) attributes simd (notinbranch) if('x32') !GCC$ builtin (cosf) attributes simd (notinbranch) if('x32') @@ -109,3 +111,5 @@ !GCC$ builtin (acoshf) attributes simd (notinbranch) if('x32') !GCC$ builtin (erf) attributes simd (notinbranch) if('x32') !GCC$ builtin (erff) attributes simd (notinbranch) if('x32') +!GCC$ builtin (tanh) attributes simd (notinbranch) if('x32') +!GCC$ builtin (tanhf) attributes simd (notinbranch) if('x32') diff --git a/sysdeps/x86_64/fpu/Makeconfig b/sysdeps/x86_64/fpu/Makeconfig index 2b89a1bba3..26df8d47bf 100644 --- a/sysdeps/x86_64/fpu/Makeconfig +++ b/sysdeps/x86_64/fpu/Makeconfig @@ -45,6 +45,7 @@ libmvec-funcs = \ sin \ sincos \ sinh \ + tanh \ # Define libmvec function for benchtests directory. libmvec-bench-funcs = \ diff --git a/sysdeps/x86_64/fpu/Versions b/sysdeps/x86_64/fpu/Versions index 2fcdef6944..adcbe0fefb 100644 --- a/sysdeps/x86_64/fpu/Versions +++ b/sysdeps/x86_64/fpu/Versions @@ -29,6 +29,7 @@ libmvec { _ZGVbN2v_log1p; _ZGVcN4v_log1p; _ZGVdN4v_log1p; _ZGVeN8v_log1p; _ZGVbN2v_log2; _ZGVcN4v_log2; _ZGVdN4v_log2; _ZGVeN8v_log2; _ZGVbN2v_sinh; _ZGVcN4v_sinh; _ZGVdN4v_sinh; _ZGVeN8v_sinh; + _ZGVbN2v_tanh; _ZGVcN4v_tanh; _ZGVdN4v_tanh; _ZGVeN8v_tanh; _ZGVbN2vv_atan2; _ZGVcN4vv_atan2; _ZGVdN4vv_atan2; _ZGVeN8vv_atan2; _ZGVbN2vv_hypot; _ZGVcN4vv_hypot; _ZGVdN4vv_hypot; _ZGVeN8vv_hypot; _ZGVbN4v_acosf; _ZGVcN8v_acosf; _ZGVdN8v_acosf; _ZGVeN16v_acosf; @@ -46,6 +47,7 @@ libmvec { _ZGVbN4v_log1pf; _ZGVcN8v_log1pf; _ZGVdN8v_log1pf; _ZGVeN16v_log1pf; _ZGVbN4v_log2f; _ZGVcN8v_log2f; _ZGVdN8v_log2f; _ZGVeN16v_log2f; _ZGVbN4v_sinhf; _ZGVcN8v_sinhf; _ZGVdN8v_sinhf; _ZGVeN16v_sinhf; + _ZGVbN4v_tanhf; _ZGVcN8v_tanhf; _ZGVdN8v_tanhf; _ZGVeN16v_tanhf; _ZGVbN4vv_atan2f; _ZGVcN8vv_atan2f; _ZGVdN8vv_atan2f; _ZGVeN16vv_atan2f; _ZGVbN4vv_hypotf; _ZGVcN8vv_hypotf; _ZGVdN8vv_hypotf; _ZGVeN16vv_hypotf; } diff --git a/sysdeps/x86_64/fpu/libm-test-ulps b/sysdeps/x86_64/fpu/libm-test-ulps index 929de0e786..bfaad7acef 100644 --- a/sysdeps/x86_64/fpu/libm-test-ulps +++ b/sysdeps/x86_64/fpu/libm-test-ulps @@ -2067,6 +2067,21 @@ float: 3 float128: 3 ldouble: 4 +Function: "tanh_vlen16": +float: 1 + +Function: "tanh_vlen2": +double: 1 + +Function: "tanh_vlen4": +double: 1 + +Function: "tanh_vlen4_avx2": +double: 1 + +Function: "tanh_vlen8": +double: 1 + Function: "tgamma": double: 9 float: 8 diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_tanh2_core-sse2.S b/sysdeps/x86_64/fpu/multiarch/svml_d_tanh2_core-sse2.S new file mode 100644 index 0000000000..35b065fe55 --- /dev/null +++ b/sysdeps/x86_64/fpu/multiarch/svml_d_tanh2_core-sse2.S @@ -0,0 +1,20 @@ +/* SSE2 version of vectorized tanh, vector length is 2. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#define _ZGVbN2v_tanh _ZGVbN2v_tanh_sse2 +#include "../svml_d_tanh2_core.S" diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_tanh2_core.c b/sysdeps/x86_64/fpu/multiarch/svml_d_tanh2_core.c new file mode 100644 index 0000000000..d2e63bdc56 --- /dev/null +++ b/sysdeps/x86_64/fpu/multiarch/svml_d_tanh2_core.c @@ -0,0 +1,27 @@ +/* Multiple versions of vectorized tanh, vector length is 2. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#define SYMBOL_NAME _ZGVbN2v_tanh +#include "ifunc-mathvec-sse4_1.h" + +libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ()); + +#ifdef SHARED +__hidden_ver1 (_ZGVbN2v_tanh, __GI__ZGVbN2v_tanh, __redirect__ZGVbN2v_tanh) + __attribute__ ((visibility ("hidden"))); +#endif diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_tanh2_core_sse4.S b/sysdeps/x86_64/fpu/multiarch/svml_d_tanh2_core_sse4.S new file mode 100644 index 0000000000..35bbb5b04c --- /dev/null +++ b/sysdeps/x86_64/fpu/multiarch/svml_d_tanh2_core_sse4.S @@ -0,0 +1,1272 @@ +/* Function tanh vectorized with SSE4. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + https://www.gnu.org/licenses/. */ + +/* + * ALGORITHM DESCRIPTION: + * + * NOTE: Since the hyperbolic tangent function is odd + * (tanh(x) = -tanh(-x)), below algorithm deals with the absolute + * value of the argument |x|: tanh(x) = sign(x) * tanh(|x|) + * + * We use a table lookup method to compute tanh(|x|). + * The basic idea is to split the input range into a number of subintervals + * and to approximate tanh(.) with a polynomial on each of them. |
