PPC64: First in the series of patches implementing POWER8 vector math.

Message ID 7z03WSXwPIOYABvW1ZYzHobMOv90wBWKo-e0YptRFovFUpRnrSEGN-zv08kOe_fPJMFnHx1khbcfcfooubTStEAtMX96Q2U4cRVZOm_TZl8=@protonmail.com
State Superseded
Headers

Commit Message

GT Feb. 14, 2019, 8:56 p.m. UTC
  Empty Message
  

Comments

Joseph Myers Feb. 14, 2019, 9:17 p.m. UTC | #1
If you have a copyright assignment / employer disclaimer on file at the 
FSF, could you give details of the names involved?

>         * sysdeps/powerpc/powerpc64/multiarch/test-double-vlen2.c: New file.

Why?  x86_64 doesn't have this.

> +#if defined _ARCH_PPC64 && defined __FAST_MATH__

Is _ARCH_PPC64 correct here - what's the status of support (in the GNU 
toolchain, Linux kernel, etc.) for -mpowerpc64 with the 32-bit ABI (which 
also defines _ARCH_PPC64)?

> diff --git a/sysdeps/powerpc/powerpc64/fpu/Versions b/sysdeps/powerpc/powerpc64/fpu/Versions
> new file mode 100644
> index 0000000000..9da7f92ffe
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc64/fpu/Versions
> @@ -0,0 +1,6 @@
> +libmvec {
> +  GLIBC_2.30 {
> +    _ZGVbN2v_cos;
> +  }
> +}
> +

You can't push commits that add blank lines at end of files; the 
repository blocks such pushes.

> diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/math-tests-arch.h b/sysdeps/powerpc/powerpc64/fpu/multiarch/math-tests-arch.h
> new file mode 100644
> index 0000000000..e79b98480b
> --- /dev/null
> +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/math-tests-arch.h
> @@ -0,0 +1,19 @@
> +/*
> +   Copyright (C) 2019 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
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <sysdeps/generic/math-tests-arch.h>

This file is useless (the only point of a sysdeps file that just includes 
the generic version would be to override a file in another sysdeps 
directory that would otherwise be used).

> +vector double _ZGVbN2v_cos_vsx (vector double x)
> +{
> +
> +/*
> +   ARGUMENT RANGE REDUCTION:
> +   Add Pi/2 to argument: X' = X+Pi/2
> + */
> +    vector double x_prime = (vector double) *dHalfPI + x;

Code formatting needs fixing to follow the GNU Coding Standards, here and 
elsewhere in the patch.

> +#include <altivec.h>
> +
> +vector unsigned long long dHalfPI_t   =
> +{0x3ff921fb54442d18,0x3ff921fb54442d18};

There are namespace problems here.  All external constants should have 
names in the implementation namespace, meaning two leading underscores.  
They should also be const; don't add new writable global variables.  In 
addition, use vector double and hex floats, rather than writing out the 
integer representation.  In addition, each constant should have a comment 
explaining its semantics, sufficiently precisely that someone could 
recompute the value and verify its correctness.
  
Steve Ellcey Feb. 15, 2019, 4:45 p.m. UTC | #2
I am curious, have patches been sent or will patches be sent to GCC to
generate calls to vector functions.  I do not see any of the
TARGET_SIMD_CLONE* macros defined for power8 in the GCC tree so I don't
see how it would ever generate calls to the vector functions.

I am also not clear on how we decide on the mangling of the vector
function names, particularly the 'b'.  I know that x86 uses 'b', 'c',
'd', or 'e' depending on the FP vectors available.  Aarch64 is using
'n' in its name mangling (and maybe something else for SVE).  Is it OK
for Power8 to use the same letter as x86?  I don't know if this is
covered in some standard or how the letters were chosen.

Steve Ellcey
sellcey@marvell.com
  
GT Feb. 15, 2019, 8:33 p.m. UTC | #3
‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Thursday, February 14, 2019 9:17 PM, Joseph Myers <joseph@codesourcery.com> wrote:

> If you have a copyright assignment / employer disclaimer on file at the
> FSF, could you give details of the names involved?
>

I emailed an electronically signed copyright assignment to assign@gnu.org a little while ago. The name is Bert Tenjy and there are no employers/schools/other who could claim any contributions by me.

> >         * sysdeps/powerpc/powerpc64/multiarch/test-double-vlen2.c: New file.
> >
>
> Why? x86_64 doesn't have this.
>

I have been shadowing the sequence of function implementation and testing done by x86_64. Looking further ahead, there was a significant reorganization of the testing procedure which removed multiple files, including the one in question here. I will rewrite PPC64 testing to fit into the current testing infrastructure.

> > +#if defined _ARCH_PPC64 && defined FAST_MATH
>
> Is _ARCH_PPC64 correct here - what's the status of support (in the GNU
> toolchain, Linux kernel, etc.) for -mpowerpc64 with the 32-bit ABI (which
> also defines _ARCH_PPC64)?
>

To address the support issues raised, a solution would be to have 'configure' verify that the compiler generates a valid executable. Then _ARCH_PPC64 would be replaced here by a macro determined at configuration time.

> > diff --git a/sysdeps/powerpc/powerpc64/fpu/Versions b/sysdeps/powerpc/powerpc64/fpu/Versions
> > new file mode 100644
> > index 0000000000..9da7f92ffe
> > --- /dev/null
> > +++ b/sysdeps/powerpc/powerpc64/fpu/Versions
> > @@ -0,0 +1,6 @@
> > +libmvec {
> >
> > -   GLIBC_2.30 {
> > -   _ZGVbN2v_cos;
> > -   }
> >     +}
> >
> > -
>
> You can't push commits that add blank lines at end of files; the
> repository blocks such pushes.
>

Will ensure no such blank lines in any file.

> > diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/math-tests-arch.h b/sysdeps/powerpc/powerpc64/fpu/multiarch/math-tests-arch.h
> > new file mode 100644
> > index 0000000000..e79b98480b
> > --- /dev/null
> > +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/math-tests-arch.h
> > @@ -0,0 +1,19 @@
> > +/*
> >
> > -   Copyright (C) 2019 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
> > -   http://www.gnu.org/licenses/. */
> > -
> >
> > +#include <sysdeps/generic/math-tests-arch.h>
>
> This file is useless (the only point of a sysdeps file that just includes
> the generic version would be to override a file in another sysdeps
> directory that would otherwise be used).
>

This has to do with the code not using the latest testing infrastructure. Fixing that should either preserve this file with overrides or eliminate its inclusion.

> > +vector double _ZGVbN2v_cos_vsx (vector double x)
> > +{
> > +
> > +/*
> >
> > -   ARGUMENT RANGE REDUCTION:
> > -   Add Pi/2 to argument: X' = X+Pi/2
> > -   */
> > -   vector double x_prime = (vector double) *dHalfPI + x;
>
> Code formatting needs fixing to follow the GNU Coding Standards, here and
> elsewhere in the patch.
>

Will look through the standard and adhere.

> > +#include <altivec.h>
> > +
> > +vector unsigned long long dHalfPI_t =
> > +{0x3ff921fb54442d18,0x3ff921fb54442d18};
>
> There are namespace problems here. All external constants should have
> names in the implementation namespace, meaning two leading underscores.
> They should also be const; don't add new writable global variables. In
> addition, use vector double and hex floats, rather than writing out the
> integer representation. In addition, each constant should have a comment
> explaining its semantics, sufficiently precisely that someone could
> recompute the value and verify its correctness.
>
>

Will fix.

===========
Thank.
Bert Tenjy.
  
Joseph Myers Feb. 15, 2019, 9:07 p.m. UTC | #4
On Fri, 15 Feb 2019, GT wrote:

> > > +#if defined _ARCH_PPC64 && defined FAST_MATH
> >
> > Is _ARCH_PPC64 correct here - what's the status of support (in the GNU
> > toolchain, Linux kernel, etc.) for -mpowerpc64 with the 32-bit ABI (which
> > also defines _ARCH_PPC64)?
> 
> To address the support issues raised, a solution would be to have 
> 'configure' verify that the compiler generates a valid executable. Then 
> _ARCH_PPC64 would be replaced here by a macro determined at 
> configuration time.

Since installed headers need to work for all multilibs that might share a 
compiler and a set of headers, a configure-time test isn't suitable here.  
I think __powerpc64__ is the correct thing to test as an ABI conditional 
(as opposed to an instruction set conditional) - it's what 
sysdeps/unix/sysv/linux/powerpc/bits/wordsize.h uses.
  
GT Feb. 16, 2019, 2:16 a.m. UTC | #5
‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Friday, February 15, 2019 9:07 PM, Joseph Myers <joseph@codesourcery.com> wrote:

> On Fri, 15 Feb 2019, GT wrote:
>
> > > > +#if defined _ARCH_PPC64 && defined FAST_MATH
> > >
> > > Is _ARCH_PPC64 correct here - what's the status of support (in the GNU
> > > toolchain, Linux kernel, etc.) for -mpowerpc64 with the 32-bit ABI (which
> > > also defines _ARCH_PPC64)?
> >
> > To address the support issues raised, a solution would be to have
> > 'configure' verify that the compiler generates a valid executable. Then
> > _ARCH_PPC64 would be replaced here by a macro determined at
> > configuration time.
>
> Since installed headers need to work for all multilibs that might share a
> compiler and a set of headers, a configure-time test isn't suitable here.
> I think __powerpc64__ is the correct thing to test as an ABI conditional
> (as opposed to an instruction set conditional) - it's what
> sysdeps/unix/sysv/linux/powerpc/bits/wordsize.h uses.
>

Going by Table 5.1 of the 64-bit ELFV2 ABI, __powerpc64__does appear to be the right macro to test for. I will make that change.

===========
Bert Tenjy.
  
GT Feb. 18, 2019, 6:30 p.m. UTC | #6
>
> > +#include <altivec.h>
> > +
> > +vector unsigned long long dHalfPI_t =
> > +{0x3ff921fb54442d18,0x3ff921fb54442d18};
>
> There are namespace problems here. All external constants should have
> names in the implementation namespace, meaning two leading underscores.
> They should also be const; don't add new writable global variables. In
> addition, use vector double and hex floats, rather than writing out the
> integer representation. In addition, each constant should have a comment
> explaining its semantics, sufficiently precisely that someone could
> recompute the value and verify its correctness.

I have addressed all the issues you raised except for one. I haven't been able to locate documentation which explains derivations of corrections to some constants used in the x86_64 code. Corrections to PI when used in repeated FMA operations, and corrections to 1/factorial(n) coefficients in the approximation polynomial.
I put the question of how to obtain these derivations on the mailing list, and am also still looking online for a solution.
May I resubmit the patch or is the lack of clarity regarding these constants a show-stopper?

Thanks.
Bert.
  
Tulio Magno Quites Machado Filho Feb. 18, 2019, 6:32 p.m. UTC | #7
Steve Ellcey <sellcey@marvell.com> writes:

> I am curious, have patches been sent or will patches be sent to GCC to
> generate calls to vector functions.  I do not see any of the
> TARGET_SIMD_CLONE* macros defined for power8 in the GCC tree so I don't
> see how it would ever generate calls to the vector functions.

That still has to be implemented.

> I am also not clear on how we decide on the mangling of the vector
> function names, particularly the 'b'.  I know that x86 uses 'b', 'c',
> 'd', or 'e' depending on the FP vectors available.  Aarch64 is using
> 'n' in its name mangling (and maybe something else for SVE).  Is it OK
> for Power8 to use the same letter as x86?  I don't know if this is
> covered in some standard or how the letters were chosen.

It was proposed to the X86-64 System V Application Binary Interface, but
it was refused. [1]

Another question: in the C++ ABI, "_ZGV" is reserved for guard variables.
How is this name collision being treated?

Andrew, could you help answer these questions?

[1] https://groups.google.com/d/msg/x86-64-abi/LmppCfN1rZ4/TydP1Gxr4cIJ
  
Joseph Myers Feb. 18, 2019, 6:38 p.m. UTC | #8
On Mon, 18 Feb 2019, GT wrote:

> I have addressed all the issues you raised except for one. I haven't 
> been able to locate documentation which explains derivations of 
> corrections to some constants used in the x86_64 code. Corrections to PI 
> when used in repeated FMA operations, and corrections to 1/factorial(n) 
> coefficients in the approximation polynomial. I put the question of how 
> to obtain these derivations on the mailing list, and am also still 
> looking online for a solution. May I resubmit the patch or is the lack 
> of clarity regarding these constants a show-stopper?

Well, you could copy the comments from the x86_64 code, if these are the 
same constants.

I'd expect, for example, given the comments, that __dPI1_FMA + __dPI2_FMA 
+ __dPI3_FMA (using the x86_64 names) is an approximation to pi to about 
3*53 bits, which is something that should be easy to verify.
  
GT Feb. 18, 2019, 7:13 p.m. UTC | #9
> > I am also not clear on how we decide on the mangling of the vector
> > function names, particularly the 'b'. I know that x86 uses 'b', 'c',
> > 'd', or 'e' depending on the FP vectors available. Aarch64 is using
> > 'n' in its name mangling (and maybe something else for SVE). Is it OK
> > for Power8 to use the same letter as x86? I don't know if this is
> > covered in some standard or how the letters were chosen.
>
> It was proposed to the X86-64 System V Application Binary Interface, but
> it was refused. [1]

Meaning, Power8 cannot use the 'b'?
  
Tulio Magno Quites Machado Filho Feb. 19, 2019, 7:38 p.m. UTC | #10
GT <tnggil@protonmail.com> writes:

>> > I am also not clear on how we decide on the mangling of the vector
>> > function names, particularly the 'b'. I know that x86 uses 'b', 'c',
>> > 'd', or 'e' depending on the FP vectors available. Aarch64 is using
>> > 'n' in its name mangling (and maybe something else for SVE). Is it OK
>> > for Power8 to use the same letter as x86? I don't know if this is
>> > covered in some standard or how the letters were chosen.
>>
>> It was proposed to the X86-64 System V Application Binary Interface, but
>> it was refused. [1]
>
> Meaning, Power8 cannot use the 'b'?

That's still unanswered.
My comment was actually related to:

>>> I don't know if this is covered in some standard or how the letters
>>> were chosen.
  

Patch

From 1740326ba3e5bac6c1524ad3acf6672e08f454fe Mon Sep 17 00:00:00 2001
From: Bert Tenjy <bert.tenjy@gmail.com>
Date: Thu, 14 Feb 2019 19:20:42 +0000
Subject: [PATCH] PPC64: First in the series of patches implementing POWER8
 vector math.

Implements double-precision cosine using VSX vector capability. Algorithm for
cosine is from x86_64 [commit #2193311288] adapted to PPC64.

Name-mangling exactly duplicates SSE ISA of the x86_64 ABI. The details are
at <https://groups.google.com/forum/#!topic/x86-64-abi/LmppCfN1rZ4>.

Adds tests of the new double-precision vector cosine.

[BZ #24205]
2019-02-14    <bert.tenjy@gmail.com>

        * sysdeps/powerpc/bits/math-vector.h: New file.
        * sysdeps/powerpc/fpu/libm-test-ulps (cos_vlen2): Added accuracy of
        double-precision vector cosine.
        * sysdeps/powerpc/powerpc64/fpu/Versions: New file.
        * sysdeps/powerpc/powerpc64/multiarch/Makefile (libmvec-sysdep_routines)
        (double-vlen-funcs,double-vlen-arch-ext-flags): Added build of VSX
        vector cos function and its tests.
        * sysdeps/powerpc/powerpc64/multiarch/math-tests-arch.h: New file.
        * sysdeps/powerpc/powerpc64/multiarch/test-double-vlen2-wrappers.c: New file.
        * sysdeps/powerpc/powerpc64/multiarch/test-double-vlen2.c: New file.
        * sysdeps/powerpc/powerpc64/multiarch/vec_d_cos2_core.c: New file.
        * sysdeps/powerpc/powerpc64/multiarch/vec_d_cos2_power8.c: New file.
        * sysdeps/powerpc/powerpc64/multiarch/vec_d_cos2_vmx.c: New file.
        * sysdeps/powerpc/powerpc64/multiarch/vec_d_trig_data.h: New file.
        * sysdeps/unix/sysv/linux/powerpc/powerpc64/libmvec.abilist: New file.
---
 ChangeLog                                     | 19 ++++
 sysdeps/powerpc/bits/math-vector.h            | 41 +++++++++
 sysdeps/powerpc/fpu/libm-test-ulps            |  3 +
 sysdeps/powerpc/powerpc64/fpu/Versions        |  6 ++
 .../powerpc/powerpc64/fpu/multiarch/Makefile  | 17 ++++
 .../powerpc64/fpu/multiarch/math-tests-arch.h | 19 ++++
 .../multiarch/test-double-vlen2-wrappers.c    | 24 ++++++
 .../fpu/multiarch/test-double-vlen2.c         | 23 +++++
 .../powerpc64/fpu/multiarch/vec_d_cos2_core.c | 31 +++++++
 .../fpu/multiarch/vec_d_cos2_power8.c         | 86 +++++++++++++++++++
 .../powerpc64/fpu/multiarch/vec_d_cos2_vmx.c  | 34 ++++++++
 .../powerpc64/fpu/multiarch/vec_d_trig_data.h | 86 +++++++++++++++++++
 .../linux/powerpc/powerpc64/libmvec.abilist   |  1 +
 13 files changed, 390 insertions(+)
 create mode 100644 sysdeps/powerpc/bits/math-vector.h
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/Versions
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/math-tests-arch.h
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/test-double-vlen2-wrappers.c
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/test-double-vlen2.c
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_cos2_core.c
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_cos2_power8.c
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_cos2_vmx.c
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_trig_data.h
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/libmvec.abilist

diff --git a/ChangeLog b/ChangeLog
index ab9f593a55..432405ea52 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@ 
+2019-02-14    <bert.tenjy@gmail.com>
+
+	* sysdeps/powerpc/bits/math-vector.h: New file.
+	* sysdeps/powerpc/fpu/libm-test-ulps (cos_vlen2): Added accuracy of
+	double-precision vector cosine.
+	* sysdeps/powerpc/powerpc64/fpu/Versions: New file.
+	* sysdeps/powerpc/powerpc64/multiarch/Makefile (libmvec-sysdep_routines)
+	(double-vlen-funcs,double-vlen-arch-ext-flags): Added build of VSX
+	vector cos function and its tests.
+	* sysdeps/powerpc/powerpc64/multiarch/math-tests-arch.h: New file.
+	* sysdeps/powerpc/powerpc64/multiarch/test-double-vlen2-wrappers.c: New file.
+	* sysdeps/powerpc/powerpc64/multiarch/test-double-vlen2.c: New file.
+	* sysdeps/powerpc/powerpc64/multiarch/vec_d_cos2_core.c: New file.
+	* sysdeps/powerpc/powerpc64/multiarch/vec_d_cos2_power8.c: New file.
+	* sysdeps/powerpc/powerpc64/multiarch/vec_d_cos2_vmx.c: New file.
+	* sysdeps/powerpc/powerpc64/multiarch/vec_d_trig_data.h: New file.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libmvec.abilist: New file.
+
+
 2019-02-14  Wilco Dijkstra  <wdijkstr@arm.com>
 
 	* benchtests/Makefile: Add malloc-simple benchmark.
diff --git a/sysdeps/powerpc/bits/math-vector.h b/sysdeps/powerpc/bits/math-vector.h
new file mode 100644
index 0000000000..7d3cedabcc
--- /dev/null
+++ b/sysdeps/powerpc/bits/math-vector.h
@@ -0,0 +1,41 @@ 
+/* Platform-specific SIMD declarations of math functions.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _MATH_H
+# error "Never include <bits/math-vector.h> directly;\
+ include <math.h> instead."
+#endif
+
+/* Get default empty definitions for simd declarations.  */
+#include <bits/libm-simd-decl-stubs.h>
+
+#if defined _ARCH_PPC64 && defined __FAST_MATH__
+# if defined _OPENMP && _OPENMP >= 201307
+/* OpenMP case.  */
+#  define __DECL_SIMD_ARCH_PPC64 _Pragma ("omp declare simd notinbranch")
+# elif __GNUC_PREREQ (6,0)
+/* W/o OpenMP use GCC 6.* __attribute__ ((__simd__)).  */
+#  define __DECL_SIMD_ARCH_PPC64 __attribute__ ((__simd__ ("notinbranch")))
+# endif
+
+# ifdef __DECL_SIMD_ARCH_PPC64
+#  undef __DECL_SIMD_cos
+#  define __DECL_SIMD_cos __DECL_SIMD_ARCH_PPC64
+
+# endif
+#endif
diff --git a/sysdeps/powerpc/fpu/libm-test-ulps b/sysdeps/powerpc/fpu/libm-test-ulps
index 1eec27c1dc..d392b135a7 100644
--- a/sysdeps/powerpc/fpu/libm-test-ulps
+++ b/sysdeps/powerpc/fpu/libm-test-ulps
@@ -1311,6 +1311,9 @@  ifloat128: 2
 ildouble: 5
 ldouble: 5
 
+Function: "cos_vlen2":
+double: 2
+
 Function: "cosh":
 double: 1
 float: 1
diff --git a/sysdeps/powerpc/powerpc64/fpu/Versions b/sysdeps/powerpc/powerpc64/fpu/Versions
new file mode 100644
index 0000000000..9da7f92ffe
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/Versions
@@ -0,0 +1,6 @@ 
+libmvec {
+  GLIBC_2.30 {
+    _ZGVbN2v_cos;
+  }
+}
+
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
index 39b557604c..3e9d541e75 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
@@ -42,3 +42,20 @@  CFLAGS-e_hypotf-power7.c = -mcpu=power7
 CFLAGS-s_modf-ppc64.c += -fsignaling-nans
 CFLAGS-s_modff-ppc64.c += -fsignaling-nans
 endif
+
+ifeq ($(subdir),mathvec)
+libmvec-sysdep_routines += vec_d_cos2_core vec_d_cos2_power8 \
+			   vec_d_cos2_vmx
+endif
+
+# Variables for libmvec tests.
+ifeq ($(subdir),math)
+ifeq ($(build-mathvec),yes)
+libmvec-tests += double-vlen2
+
+double-vlen2-funcs = cos
+
+double-vlen2-arch-ext-cflags = -mvsx
+
+endif
+endif
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/math-tests-arch.h b/sysdeps/powerpc/powerpc64/fpu/multiarch/math-tests-arch.h
new file mode 100644
index 0000000000..e79b98480b
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/math-tests-arch.h
@@ -0,0 +1,19 @@ 
+/*
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdeps/generic/math-tests-arch.h>
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/test-double-vlen2-wrappers.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/test-double-vlen2-wrappers.c
new file mode 100644
index 0000000000..17e2cc0724
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/test-double-vlen2-wrappers.c
@@ -0,0 +1,24 @@ 
+/* Wrapper part of tests for VSX ISA versions of vector math functions.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include "test-double-vlen2.h"
+#include <altivec.h>
+
+#define VEC_TYPE vector double
+
+VECTOR_WRAPPER (WRAPPER_NAME (cos), _ZGVbN2v_cos)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/test-double-vlen2.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/test-double-vlen2.c
new file mode 100644
index 0000000000..ca1673f103
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/test-double-vlen2.c
@@ -0,0 +1,23 @@ 
+/* Tests for VSX ISA versions of vector math functions.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include "test-double-vlen2.h"
+
+#define TEST_VECTOR_cos 1
+
+#include "libm-test.c"
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_cos2_core.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_cos2_core.c
new file mode 100644
index 0000000000..1fee72d50e
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_cos2_core.c
@@ -0,0 +1,31 @@ 
+/* Multiple versions of vectorized cos function.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <shlib-compat.h>
+#include "init-arch.h"
+
+vector double _ZGVbN2v_cos(vector double x);
+
+extern __typeof (_ZGVbN2v_cos) _ZGVbN2v_cos_vmx attribute_hidden;
+extern __typeof (_ZGVbN2v_cos) _ZGVbN2v_cos_vsx   attribute_hidden;
+
+libc_ifunc (_ZGVbN2v_cos,
+           (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+           ? _ZGVbN2v_cos_vsx
+           : _ZGVbN2v_cos_vmx);
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_cos2_power8.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_cos2_power8.c
new file mode 100644
index 0000000000..7d22434a68
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_cos2_power8.c
@@ -0,0 +1,86 @@ 
+/* Function cos vectorized with VSX.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include "vec_d_trig_data.h"
+
+vector double _ZGVbN2v_cos_vsx (vector double x)
+{
+
+/*
+   ARGUMENT RANGE REDUCTION:
+   Add Pi/2 to argument: X' = X+Pi/2
+ */
+    vector double x_prime = (vector double) *dHalfPI + x;
+
+/* Get absolute argument value: X' = |X'| */
+    vector double abs_x_prime = vec_abs(x_prime);
+
+/* Y = X'*InvPi + RS : right shifter add */
+    vector double y = (x_prime * (*dInvPI)) + *dRShifter;
+
+/* Check for large arguments path */
+    vector bool long long large_in = vec_cmpgt(abs_x_prime,*dRangeVal);
+
+/* N = Y - RS : right shifter sub */
+    vector double n = y - *dRShifter;
+
+/* SignRes = Y<<63 : shift LSB to MSB place for result sign */
+    vector double sign_res = (vector double) vec_sl((vector long long ) y,
+                                (vector unsigned long long) vec_splats(63));
+
+/* N = N - 0.5 */
+    n = n - *dOneHalf;
+
+/* R = X - N*Pi1 */
+    vector double r = x - (n * (*dPI1_FMA));
+
+/* R = R - N*Pi2 */
+    r = r - (n * (*dPI2_FMA));
+
+/* R = R - N*Pi3 */
+    r = r - (n * (*dPI3_FMA));
+
+/* R2 = R*R */
+    vector double r2 = r * r;
+
+/* Poly = C3+R2*(C4+R2*(C5+R2*(C6+R2*C7))) */
+    vector double poly = *dC3 + r2*(*dC4 + r2*(*dC5 + r2*(*dC6 + r2*(*dC7))));
+
+/* Poly = R+R*(R2*(C1+R2*(C2+R2*Poly))) */
+    poly = r + r*(r2*(*dC1 + r2*(*dC2 + r2*poly)));
+
+/*
+   RECONSTRUCTION:
+   Final sign setting: Res = Poly^SignRes */
+    vector double out = (vector double)
+        ((vector long long) poly ^ (vector long long) sign_res);
+
+    if(large_in[0])
+    {
+        out[0] = cos(x[0]);
+    }
+
+    if(large_in[1])
+    {
+        out[1] = cos(x[1]);
+    }
+
+    return out;
+
+} // _ZGVbN2v_cos_vsx
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_cos2_vmx.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_cos2_vmx.c
new file mode 100644
index 0000000000..6f92b15eb4
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_cos2_vmx.c
@@ -0,0 +1,34 @@ 
+/* PowerPC64 default version of vectorized cos function.
+   Calls scalar cos version twice.
+
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <altivec.h>
+
+vector double _ZGVbN2v_cos_vmx (vector double x)
+{
+
+    vector double out;
+
+    out[0] = cos(x[0]);
+    out[1] = cos(x[1]);
+
+    return out;
+
+} // _ZGVbN2v_cos_vmx
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_trig_data.h b/sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_trig_data.h
new file mode 100644
index 0000000000..968bc680ab
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/vec_d_trig_data.h
@@ -0,0 +1,86 @@ 
+/* Constants used in polynomail approximations for vectorized sin, cos,
+   and sincos functions.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef D_TRIG_DATA_H
+#define D_TRIG_DATA_H
+
+#include <altivec.h>
+
+vector unsigned long long dHalfPI_t   =
+{0x3ff921fb54442d18,0x3ff921fb54442d18};
+
+vector unsigned long long dInvPI_t    =
+{0x3fd45f306dc9c883,0x3fd45f306dc9c883};
+
+vector unsigned long long dRShifter_t =
+{0x4338000000000000,0x4338000000000000};
+
+vector unsigned long long dRangeVal_t =
+{0x4160000000000000,0x4160000000000000};
+
+vector unsigned long long dOneHalf_t  =
+{0x3fe0000000000000,0x3fe0000000000000};
+
+vector unsigned long long dPI1_FMA_t  =
+{0x400921fb54442d18,0x400921fb54442d18};
+
+vector unsigned long long dPI2_FMA_t  =
+{0x3ca1a62633145c06,0x3ca1a62633145c06};
+
+vector unsigned long long dPI3_FMA_t  =
+{0x395c1cd129024e09,0x395c1cd129024e09};
+
+vector unsigned long long dC7_t       =
+{0xbd69f0d60811aac8,0xbd69f0d60811aac8};
+
+vector unsigned long long dC6_t       =
+{0x3de60e6857a2f220,0x3de60e6857a2f220};
+
+vector unsigned long long dC5_t       =
+{0xbe5ae63546002231,0xbe5ae63546002231};
+
+vector unsigned long long dC4_t       =
+{0x3ec71de38030fea0,0x3ec71de38030fea0};
+
+vector unsigned long long dC3_t       =
+{0xbf2a01a019a5b86d,0xbf2a01a019a5b86d};
+
+vector unsigned long long dC2_t       =
+{0x3f8111111110a4a8,0x3f8111111110a4a8};
+
+vector unsigned long long dC1_t       =
+{0xbfc55555555554a7,0xbfc55555555554a7};
+
+vector double *dHalfPI     = (vector double *) &dHalfPI_t;
+vector double *dInvPI      = (vector double *) &dInvPI_t;
+vector double *dRShifter   = (vector double *) &dRShifter_t;
+vector double *dRangeVal   = (vector double *) &dRangeVal_t;
+vector double *dOneHalf    = (vector double *) &dOneHalf_t;
+vector double *dPI1_FMA    = (vector double *) &dPI1_FMA_t;
+vector double *dPI2_FMA    = (vector double *) &dPI2_FMA_t;
+vector double *dPI3_FMA    = (vector double *) &dPI3_FMA_t;
+vector double *dC7         = (vector double *) &dC7_t;
+vector double *dC6         = (vector double *) &dC6_t;
+vector double *dC5         = (vector double *) &dC5_t;
+vector double *dC4         = (vector double *) &dC4_t;
+vector double *dC3         = (vector double *) &dC3_t;
+vector double *dC2         = (vector double *) &dC2_t;
+vector double *dC1         = (vector double *) &dC1_t;
+
+#endif // D_TRIG_DATA_H
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libmvec.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libmvec.abilist
new file mode 100644
index 0000000000..656ce0541f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libmvec.abilist
@@ -0,0 +1 @@ 
+GLIBC_2.30 _ZGVbN2v_cos F
-- 
2.20.1