aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSunil K Pandey <skpgkp2@gmail.com>2021-12-29 08:35:22 -0800
committerSunil K Pandey <skpgkp2@gmail.com>2021-12-29 11:37:21 -0800
commit37475ba88303929e85704693455c7294e50aba77 (patch)
tree4defc4412f556258f878588351b27b3b44406fb8
parent11c01de14c879ffc8dbac8ce32242a7552cbd4ad (diff)
downloadglibc-37475ba88303929e85704693455c7294e50aba77.tar.xz
glibc-37475ba88303929e85704693455c7294e50aba77.zip
x86-64: Add vector hypot/hypotf implementation to libmvec
Implement vectorized hypot/hypotf containing SSE, AVX, AVX2 and AVX512 versions for libmvec as per vector ABI. It also contains accuracy and ABI tests for vector hypot/hypotf with regenerated ulps. Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
-rw-r--r--bits/libm-simd-decl-stubs.h11
-rw-r--r--math/bits/mathcalls.h2
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/libmvec.abilist8
-rw-r--r--sysdeps/x86/fpu/bits/math-vector.h4
-rw-r--r--sysdeps/x86/fpu/finclude/math-vector-fortran.h4
-rw-r--r--sysdeps/x86_64/fpu/Makeconfig1
-rw-r--r--sysdeps/x86_64/fpu/Versions2
-rw-r--r--sysdeps/x86_64/fpu/libm-test-ulps20
-rw-r--r--sysdeps/x86_64/fpu/multiarch/svml_d_hypot2_core-sse2.S20
-rw-r--r--sysdeps/x86_64/fpu/multiarch/svml_d_hypot2_core.c28
-rw-r--r--sysdeps/x86_64/fpu/multiarch/svml_d_hypot2_core_sse4.S279
-rw-r--r--sysdeps/x86_64/fpu/multiarch/svml_d_hypot4_core-sse.S20
-rw-r--r--sysdeps/x86_64/fpu/multiarch/svml_d_hypot4_core.c28
-rw-r--r--sysdeps/x86_64/fpu/multiarch/svml_d_hypot4_core_avx2.S289
-rw-r--r--sysdeps/x86_64/fpu/multiarch/svml_d_hypot8_core-avx2.S20
-rw-r--r--sysdeps/x86_64/fpu/multiarch/svml_d_hypot8_core.c28
-rw-r--r--sysdeps/x86_64/fpu/multiarch/svml_d_hypot8_core_avx512.S235
-rw-r--r--sysdeps/x86_64/fpu/multiarch/svml_s_hypotf16_core-avx2.S20
-rw-r--r--sysdeps/x86_64/fpu/multiarch/svml_s_hypotf16_core.c28
-rw-r--r--sysdeps/x86_64/fpu/multiarch/svml_s_hypotf16_core_avx512.S239
-rw-r--r--sysdeps/x86_64/fpu/multiarch/svml_s_hypotf4_core-sse2.S20
-rw-r--r--sysdeps/x86_64/fpu/multiarch/svml_s_hypotf4_core.c28
-rw-r--r--sysdeps/x86_64/fpu/multiarch/svml_s_hypotf4_core_sse4.S265
-rw-r--r--sysdeps/x86_64/fpu/multiarch/svml_s_hypotf8_core-sse.S20
-rw-r--r--sysdeps/x86_64/fpu/multiarch/svml_s_hypotf8_core.c28
-rw-r--r--sysdeps/x86_64/fpu/multiarch/svml_s_hypotf8_core_avx2.S269
-rw-r--r--sysdeps/x86_64/fpu/svml_d_hypot2_core.S29
-rw-r--r--sysdeps/x86_64/fpu/svml_d_hypot4_core.S29
-rw-r--r--sysdeps/x86_64/fpu/svml_d_hypot4_core_avx.S25
-rw-r--r--sysdeps/x86_64/fpu/svml_d_hypot8_core.S25
-rw-r--r--sysdeps/x86_64/fpu/svml_s_hypotf16_core.S25
-rw-r--r--sysdeps/x86_64/fpu/svml_s_hypotf4_core.S29
-rw-r--r--sysdeps/x86_64/fpu/svml_s_hypotf8_core.S29
-rw-r--r--sysdeps/x86_64/fpu/svml_s_hypotf8_core_avx.S25
-rw-r--r--sysdeps/x86_64/fpu/test-double-libmvec-hypot-avx.c1
-rw-r--r--sysdeps/x86_64/fpu/test-double-libmvec-hypot-avx2.c1
-rw-r--r--sysdeps/x86_64/fpu/test-double-libmvec-hypot-avx512f.c1
-rw-r--r--sysdeps/x86_64/fpu/test-double-libmvec-hypot.c3
-rw-r--r--sysdeps/x86_64/fpu/test-double-vlen2-wrappers.c1
-rw-r--r--sysdeps/x86_64/fpu/test-double-vlen4-avx2-wrappers.c1
-rw-r--r--sysdeps/x86_64/fpu/test-double-vlen4-wrappers.c1
-rw-r--r--sysdeps/x86_64/fpu/test-double-vlen8-wrappers.c1
-rw-r--r--sysdeps/x86_64/fpu/test-float-libmvec-hypotf-avx.c1
-rw-r--r--sysdeps/x86_64/fpu/test-float-libmvec-hypotf-avx2.c1
-rw-r--r--sysdeps/x86_64/fpu/test-float-libmvec-hypotf-avx512f.c1
-rw-r--r--sysdeps/x86_64/fpu/test-float-libmvec-hypotf.c3
-rw-r--r--sysdeps/x86_64/fpu/test-float-vlen16-wrappers.c1
-rw-r--r--sysdeps/x86_64/fpu/test-float-vlen4-wrappers.c1
-rw-r--r--sysdeps/x86_64/fpu/test-float-vlen8-avx2-wrappers.c1
-rw-r--r--sysdeps/x86_64/fpu/test-float-vlen8-wrappers.c1
50 files changed, 2151 insertions, 1 deletions
diff --git a/bits/libm-simd-decl-stubs.h b/bits/libm-simd-decl-stubs.h
index ae8ee882d0..adf65f6bc2 100644
--- a/bits/libm-simd-decl-stubs.h
+++ b/bits/libm-simd-decl-stubs.h
@@ -131,4 +131,15 @@
#define __DECL_SIMD_asinf32x
#define __DECL_SIMD_asinf64x
#define __DECL_SIMD_asinf128x
+
+#define __DECL_SIMD_hypot
+#define __DECL_SIMD_hypotf
+#define __DECL_SIMD_hypotl
+#define __DECL_SIMD_hypotf16
+#define __DECL_SIMD_hypotf32
+#define __DECL_SIMD_hypotf64
+#define __DECL_SIMD_hypotf128
+#define __DECL_SIMD_hypotf32x
+#define __DECL_SIMD_hypotf64x
+#define __DECL_SIMD_hypotf128x
#endif
diff --git a/math/bits/mathcalls.h b/math/bits/mathcalls.h
index bb53b7021e..2ed820a0dc 100644
--- a/math/bits/mathcalls.h
+++ b/math/bits/mathcalls.h
@@ -144,7 +144,7 @@ __MATHCALL (sqrt,, (_Mdouble_ __x));
#if defined __USE_XOPEN || defined __USE_ISOC99
/* Return `sqrt(X*X + Y*Y)'. */
-__MATHCALL (hypot,, (_Mdouble_ __x, _Mdouble_ __y));
+__MATHCALL_VEC (hypot,, (_Mdouble_ __x, _Mdouble_ __y));
#endif
#if defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
diff --git a/sysdeps/unix/sysv/linux/x86_64/libmvec.abilist b/sysdeps/unix/sysv/linux/x86_64/libmvec.abilist
index ab03a07f92..12bb03245b 100644
--- a/sysdeps/unix/sysv/linux/x86_64/libmvec.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/libmvec.abilist
@@ -49,24 +49,32 @@ GLIBC_2.22 _ZGVeN8vvv_sincos F
GLIBC_2.35 _ZGVbN2v_acos F
GLIBC_2.35 _ZGVbN2v_asin F
GLIBC_2.35 _ZGVbN2v_atan F
+GLIBC_2.35 _ZGVbN2vv_hypot F
GLIBC_2.35 _ZGVbN4v_acosf F
GLIBC_2.35 _ZGVbN4v_asinf F
GLIBC_2.35 _ZGVbN4v_atanf F
+GLIBC_2.35 _ZGVbN4vv_hypotf F
GLIBC_2.35 _ZGVcN4v_acos F
GLIBC_2.35 _ZGVcN4v_asin F
GLIBC_2.35 _ZGVcN4v_atan F
+GLIBC_2.35 _ZGVcN4vv_hypot F
GLIBC_2.35 _ZGVcN8v_acosf F
GLIBC_2.35 _ZGVcN8v_asinf F
GLIBC_2.35 _ZGVcN8v_atanf F
+GLIBC_2.35 _ZGVcN8vv_hypotf F
GLIBC_2.35 _ZGVdN4v_acos F
GLIBC_2.35 _ZGVdN4v_asin F
GLIBC_2.35 _ZGVdN4v_atan F
+GLIBC_2.35 _ZGVdN4vv_hypot F
GLIBC_2.35 _ZGVdN8v_acosf F
GLIBC_2.35 _ZGVdN8v_asinf F
GLIBC_2.35 _ZGVdN8v_atanf F
+GLIBC_2.35 _ZGVdN8vv_hypotf F
GLIBC_2.35 _ZGVeN16v_acosf F
GLIBC_2.35 _ZGVeN16v_asinf F
GLIBC_2.35 _ZGVeN16v_atanf F
+GLIBC_2.35 _ZGVeN16vv_hypotf F
GLIBC_2.35 _ZGVeN8v_acos F
GLIBC_2.35 _ZGVeN8v_asin F
GLIBC_2.35 _ZGVeN8v_atan 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 73cb8849ff..437977c5fd 100644
--- a/sysdeps/x86/fpu/bits/math-vector.h
+++ b/sysdeps/x86/fpu/bits/math-vector.h
@@ -70,6 +70,10 @@
# define __DECL_SIMD_asin __DECL_SIMD_x86_64
# undef __DECL_SIMD_asinf
# define __DECL_SIMD_asinf __DECL_SIMD_x86_64
+# undef __DECL_SIMD_hypot
+# define __DECL_SIMD_hypot __DECL_SIMD_x86_64
+# undef __DECL_SIMD_hypotf
+# define __DECL_SIMD_hypotf __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 4552c2bdfa..cda31479a6 100644
--- a/sysdeps/x86/fpu/finclude/math-vector-fortran.h
+++ b/sysdeps/x86/fpu/finclude/math-vector-fortran.h
@@ -34,6 +34,8 @@
!GCC$ builtin (atanf) attributes simd (notinbranch) if('x86_64')
!GCC$ builtin (asin) attributes simd (notinbranch) if('x86_64')
!GCC$ builtin (asinf) attributes simd (notinbranch) if('x86_64')
+!GCC$ builtin (hypot) attributes simd (notinbranch) if('x86_64')
+!GCC$ builtin (hypotf) attributes simd (notinbranch) if('x86_64')
!GCC$ builtin (cos) attributes simd (notinbranch) if('x32')
!GCC$ builtin (cosf) attributes simd (notinbranch) if('x32')
@@ -53,3 +55,5 @@
!GCC$ builtin (atanf) attributes simd (notinbranch) if('x32')
!GCC$ builtin (asin) attributes simd (notinbranch) if('x32')
!GCC$ builtin (asinf) attributes simd (notinbranch) if('x32')
+!GCC$ builtin (hypot) attributes simd (notinbranch) if('x32')
+!GCC$ builtin (hypotf) attributes simd (notinbranch) if('x32')
diff --git a/sysdeps/x86_64/fpu/Makeconfig b/sysdeps/x86_64/fpu/Makeconfig
index e0eae0b196..7769a02731 100644
--- a/sysdeps/x86_64/fpu/Makeconfig
+++ b/sysdeps/x86_64/fpu/Makeconfig
@@ -27,6 +27,7 @@ libmvec-funcs = \
atan \
cos \
exp \
+ hypot \
log \
pow \
sin \
diff --git a/sysdeps/x86_64/fpu/Versions b/sysdeps/x86_64/fpu/Versions
index 10baf869a5..e359e5dc2c 100644
--- a/sysdeps/x86_64/fpu/Versions
+++ b/sysdeps/x86_64/fpu/Versions
@@ -17,8 +17,10 @@ libmvec {
_ZGVbN2v_acos; _ZGVcN4v_acos; _ZGVdN4v_acos; _ZGVeN8v_acos;
_ZGVbN2v_asin; _ZGVcN4v_asin; _ZGVdN4v_asin; _ZGVeN8v_asin;
_ZGVbN2v_atan; _ZGVcN4v_atan; _ZGVdN4v_atan; _ZGVeN8v_atan;
+ _ZGVbN2vv_hypot; _ZGVcN4vv_hypot; _ZGVdN4vv_hypot; _ZGVeN8vv_hypot;
_ZGVbN4v_acosf; _ZGVcN8v_acosf; _ZGVdN8v_acosf; _ZGVeN16v_acosf;
_ZGVbN4v_asinf; _ZGVcN8v_asinf; _ZGVdN8v_asinf; _ZGVeN16v_asinf;
_ZGVbN4v_atanf; _ZGVcN8v_atanf; _ZGVdN8v_atanf; _ZGVeN16v_atanf;
+ _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 ea0f833381..a7513ec94e 100644
--- a/sysdeps/x86_64/fpu/libm-test-ulps
+++ b/sysdeps/x86_64/fpu/libm-test-ulps
@@ -1375,6 +1375,26 @@ double: 1
float128: 1
ldouble: 1
+Function: "hypot_vlen16":
+float: 1
+
+Function: "hypot_vlen2":
+double: 1
+
+Function: "hypot_vlen4":
+double: 1
+float: 1
+
+Function: "hypot_vlen4_avx2":
+double: 1
+
+Function: "hypot_vlen8":
+double: 1
+float: 1
+
+Function: "hypot_vlen8_avx2":
+float: 1
+
Function: "j0":
double: 3
float: 9
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_hypot2_core-sse2.S b/sysdeps/x86_64/fpu/multiarch/svml_d_hypot2_core-sse2.S
new file mode 100644
index 0000000000..237e38459e
--- /dev/null
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_hypot2_core-sse2.S
@@ -0,0 +1,20 @@
+/* SSE2 version of vectorized hypot.
+ 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 _ZGVbN2vv_hypot _ZGVbN2vv_hypot_sse2
+#include "../svml_d_hypot2_core.S"
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_hypot2_core.c b/sysdeps/x86_64/fpu/multiarch/svml_d_hypot2_core.c
new file mode 100644
index 0000000000..3f0865f05d
--- /dev/null
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_hypot2_core.c
@@ -0,0 +1,28 @@
+/* Multiple versions of vectorized hypot, 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 _ZGVbN2vv_hypot
+#include "ifunc-mathvec-sse4_1.h"
+
+libc_ifunc_redirected (REDIRECT_NAME, SYMBOL_NAME, IFUNC_SELECTOR ());
+
+#ifdef SHARED
+__hidden_ver1 (_ZGVbN2vv_hypot, __GI__ZGVbN2vv_hypot,
+ __redirect__ZGVbN2vv_hypot)
+ __attribute__ ((visibility ("hidden")));
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/svml_d_hypot2_core_sse4.S b/sysdeps/x86_64/fpu/multiarch/svml_d_hypot2_core_sse4.S
new file mode 100644
index 0000000000..931f34e5f2
--- /dev/null
+++ b/sysdeps/x86_64/fpu/multiarch/svml_d_hypot2_core_sse4.S
@@ -0,0 +1,279 @@
+/* Function hypot 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:
+ *
+ * HIGH LEVEL OVERVIEW
+ *
+ * Calculate z = (x*x+y*y)
+ * Calculate reciplicle sqrt (z)
+ * Calculate error = z*(rsqrt(z)*rsqrt(z)) - 1
+ * Calculate fixing part p with polynom
+ * Fix answer with sqrt(z) = z * rsqrt(z) + error * p * z
+ *
+ * ALGORITHM DETAILS
+ *
+ * Multiprecision branch for _HA_ only
+ * Remove sigm from both arguments
+ * Find maximum (_x) and minimum (_y) (by abs va