[1/1] Add IFUNC POWER optimization for e_pow and e_exp

Message ID 20170709182430.91459-2-juvenal.silva.jr@gmail.com
State New
Headers show
Series
  • Add IFUNC POWER optimization for e_pow and e_exp
Related show

Commit Message

Juvenal Silva July 9, 2017, 6:24 p.m.
This patch proposes a change to provide at least crude optimizations for some
POWER architecture versions, based on IFUNC and a custom -mcpu gcc directive.
This patch covers two of the POWER GLIBC Master Todo List items, 'Optimize
math functions for P7: __ieee754_exp, __ieee754_pow, __dubsin'.
This is also a proof of concept for a base performance gain strategy.

2017-01-31  Juvenal A. Silva Jr.  <juvenal.silva.jr@gmail.com>

	* sysdeps/ieee754/dbl-64/e-pow.c: Fix a comment aligment problem.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile: Add entries for
	custom build of CPU specific versions of e_pow and e_exp.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow.c: New file
	* sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-ppc64.c: New file.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-power7.c: New file.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-power8.c: New file.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-power9.c: New file.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-ppc64.c: New file.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-power7.c: New file.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-power8.c: New file.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-power9.c: New file.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp.c: New file
	* sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-ppc64.c: New file.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-power7.c: New file.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-power8.c: New file.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-power9.c: New file.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/slowexp-ppc64.c: New file.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/slowexp-power7.c: New file.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/slowexp-power8.c: New file.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/slowexp-power9.c: New file.
---
 sysdeps/ieee754/dbl-64/e_pow.c                     |  2 +-
 sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile   | 18 ++++++++++-
 .../powerpc/powerpc64/fpu/multiarch/e_exp-power7.c | 28 ++++++++++++++++
 .../powerpc/powerpc64/fpu/multiarch/e_exp-power8.c | 28 ++++++++++++++++
 .../powerpc/powerpc64/fpu/multiarch/e_exp-power9.c | 28 ++++++++++++++++
 .../powerpc/powerpc64/fpu/multiarch/e_exp-ppc64.c  | 26 +++++++++++++++
 sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp.c    | 37 ++++++++++++++++++++++
 .../powerpc/powerpc64/fpu/multiarch/e_pow-power7.c | 28 ++++++++++++++++
 .../powerpc/powerpc64/fpu/multiarch/e_pow-power8.c | 28 ++++++++++++++++
 .../powerpc/powerpc64/fpu/multiarch/e_pow-power9.c | 28 ++++++++++++++++
 .../powerpc/powerpc64/fpu/multiarch/e_pow-ppc64.c  | 26 +++++++++++++++
 sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow.c    | 37 ++++++++++++++++++++++
 .../powerpc64/fpu/multiarch/slowexp-power7.c       | 26 +++++++++++++++
 .../powerpc64/fpu/multiarch/slowexp-power8.c       | 26 +++++++++++++++
 .../powerpc64/fpu/multiarch/slowexp-power9.c       | 26 +++++++++++++++
 .../powerpc64/fpu/multiarch/slowexp-ppc64.c        | 24 ++++++++++++++
 .../powerpc64/fpu/multiarch/slowpow-power7.c       | 26 +++++++++++++++
 .../powerpc64/fpu/multiarch/slowpow-power8.c       | 26 +++++++++++++++
 .../powerpc64/fpu/multiarch/slowpow-power9.c       | 26 +++++++++++++++
 .../powerpc64/fpu/multiarch/slowpow-ppc64.c        | 24 ++++++++++++++
 20 files changed, 516 insertions(+), 2 deletions(-)
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-power7.c
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-power8.c
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-power9.c
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-ppc64.c
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp.c
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-power7.c
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-power8.c
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-power9.c
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-ppc64.c
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow.c
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/slowexp-power7.c
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/slowexp-power8.c
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/slowexp-power9.c
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/slowexp-ppc64.c
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-power7.c
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-power8.c
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-power9.c
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-ppc64.c

-- 
2.13.2

Comments

Tulio Magno Quites Machado Filho Sept. 20, 2017, 9 p.m. | #1
"Juvenal A. Silva Jr" <juvenal.silva.jr@gmail.com> writes:

> 2017-01-31  Juvenal A. Silva Jr.  <juvenal.silva.jr@gmail.com>

>

> 	* sysdeps/ieee754/dbl-64/e-pow.c: Fix a comment aligment problem.

> 	* sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile: Add entries for

> 	custom build of CPU specific versions of e_pow and e_exp.

> 	* sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow.c: New file

> 	* sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-ppc64.c: New file.

> 	* sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-power7.c: New file.

> 	* sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-power8.c: New file.

> 	* sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-power9.c: New file.

> 	* sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-ppc64.c: New file.

> 	* sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-power7.c: New file.

> 	* sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-power8.c: New file.

> 	* sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-power9.c: New file.

> 	* sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp.c: New file

> 	* sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-ppc64.c: New file.

> 	* sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-power7.c: New file.


There has been a recent contribution of e_exp-ppc64 and e_exp-power7.
So, I had to remove both files from your patch before applying it.

> 	* sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-power8.c: New file.

> 	* sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-power9.c: New file.


In my tests using the benchtests, both these functions were not able to beat
the current implementation from e_exp-power7.c.

> diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile

> index d6f14f360a..8bd508747b 100644

> --- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile

> +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile

> @@ -27,7 +27,11 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \

>  			s_llrint-power8 s_llround-power8 s_llroundf-ppc64 \

>  			e_expf-power8 e_expf-ppc64 \

>  			s_sinf-ppc64 s_sinf-power8 \

> -			s_cosf-ppc64 s_cosf-power8

> +			s_cosf-ppc64 s_cosf-power8 \

> +			slowpow-power7 slowpow-power8 slowpow-power9 slowpow-ppc64 \

> +			e_pow-power7 e_pow-power8 e_pow-power9 e_pow-ppc64 \

> +			slowexp-power7 slowexp-power8 slowexp-power9 slowexp-ppc64 \

> +			e_exp-power7 e_exp-power8 e_exp-power9 e_exp-ppc64

>

>  CFLAGS-s_logbf-power7.c = -mcpu=power7

>  CFLAGS-s_logbl-power7.c = -mcpu=power7

> @@ -36,6 +40,18 @@ CFLAGS-s_modf-power5+.c = -mcpu=power5+

>  CFLAGS-s_modff-power5+.c = -mcpu=power5+

>  CFLAGS-e_hypot-power7.c = -mcpu=power7

>  CFLAGS-e_hypotf-power7.c = -mcpu=power7

> +CFLAGS-slowpow-power7.c = -mcpu=power7

> +CFLAGS-slowpow-power8.c = -mcpu=power8

> +CFLAGS-slowpow-power9.c = -mcpu=power9

> +CFLAGS-e_pow-power7.c = -mcpu=power7

> +CFLAGS-e_pow-power8.c = -mcpu=power8

> +CFLAGS-e_pow-power9.c = -mcpu=power9


The default pow() implementation must not be compiled this way.  It requires
to use $(config-cflags-nofma) in order to avoid increasing the error of the
function too much (165 ulp).

Unfortunately, after using it, there is no performance improvement.

-- 
Tulio Magno
Juvenal Silva Sept. 23, 2017, 4:25 a.m. | #2
Hi Tulio,

Thanks for spending some time reviewing this.

---
Juvenal A. Silva Jr.

> On 20 Sep 2017, at 18:00, Tulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com> wrote:

> 

> "Juvenal A. Silva Jr" <juvenal.silva.jr@gmail.com> writes:

> 

>> 2017-01-31  Juvenal A. Silva Jr.  <juvenal.silva.jr@gmail.com>

>> 

>>    * sysdeps/ieee754/dbl-64/e-pow.c: Fix a comment aligment problem.

>>    * sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile: Add entries for

>>    custom build of CPU specific versions of e_pow and e_exp.

>>    * sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow.c: New file

>>    * sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-ppc64.c: New file.

>>    * sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-power7.c: New file.

>>    * sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-power8.c: New file.

>>    * sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-power9.c: New file.

>>    * sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-ppc64.c: New file.

>>    * sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-power7.c: New file.

>>    * sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-power8.c: New file.

>>    * sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-power9.c: New file.

>>    * sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp.c: New file

>>    * sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-ppc64.c: New file.

>>    * sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-power7.c: New file.

> 

> There has been a recent contribution of e_exp-ppc64 and e_exp-power7.

> So, I had to remove both files from your patch before applying it.

> 

>>    * sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-power8.c: New file.

>>    * sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-power9.c: New file.

> 

> In my tests using the benchtests, both these functions were not able to beat

> the current implementation from e_exp-power7.c.

> 

>> diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile

>> index d6f14f360a..8bd508747b 100644

>> --- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile

>> +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile

>> @@ -27,7 +27,11 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \

>>            s_llrint-power8 s_llround-power8 s_llroundf-ppc64 \

>>            e_expf-power8 e_expf-ppc64 \

>>            s_sinf-ppc64 s_sinf-power8 \

>> -            s_cosf-ppc64 s_cosf-power8

>> +            s_cosf-ppc64 s_cosf-power8 \

>> +            slowpow-power7 slowpow-power8 slowpow-power9 slowpow-ppc64 \

>> +            e_pow-power7 e_pow-power8 e_pow-power9 e_pow-ppc64 \

>> +            slowexp-power7 slowexp-power8 slowexp-power9 slowexp-ppc64 \

>> +            e_exp-power7 e_exp-power8 e_exp-power9 e_exp-ppc64

>> 

>> CFLAGS-s_logbf-power7.c = -mcpu=power7

>> CFLAGS-s_logbl-power7.c = -mcpu=power7

>> @@ -36,6 +40,18 @@ CFLAGS-s_modf-power5+.c = -mcpu=power5+

>> CFLAGS-s_modff-power5+.c = -mcpu=power5+

>> CFLAGS-e_hypot-power7.c = -mcpu=power7

>> CFLAGS-e_hypotf-power7.c = -mcpu=power7

>> +CFLAGS-slowpow-power7.c = -mcpu=power7

>> +CFLAGS-slowpow-power8.c = -mcpu=power8

>> +CFLAGS-slowpow-power9.c = -mcpu=power9

>> +CFLAGS-e_pow-power7.c = -mcpu=power7

>> +CFLAGS-e_pow-power8.c = -mcpu=power8

>> +CFLAGS-e_pow-power9.c = -mcpu=power9

> 

> The default pow() implementation must not be compiled this way.  It requires

> to use $(config-cflags-nofma) in order to avoid increasing the error of the

> function too much (165 ulp).

> 

> Unfortunately, after using it, there is no performance improvement.

> 

> -- 

> Tulio Magno

>

Patch

diff --git a/sysdeps/ieee754/dbl-64/e_pow.c b/sysdeps/ieee754/dbl-64/e_pow.c
index 9f6439ee42..45a485c52a 100644
--- a/sysdeps/ieee754/dbl-64/e_pow.c
+++ b/sysdeps/ieee754/dbl-64/e_pow.c
@@ -26,7 +26,7 @@ 
 /*             checkint                                                    */
 /* FILES NEEDED: dla.h endian.h mpa.h mydefs.h                             */
 /*               halfulp.c mpexp.c mplog.c slowexp.c slowpow.c mpa.c       */
-/*                          uexp.c  upow.c				   */
+/*                          uexp.c  upow.c                                 */
 /*               root.tbl uexp.tbl upow.tbl                                */
 /* An ultimate power routine. Given two IEEE double machine numbers y,x    */
 /* it computes the correctly rounded (to nearest) value of x^y.            */
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
index d6f14f360a..8bd508747b 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
@@ -27,7 +27,11 @@  libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
 			s_llrint-power8 s_llround-power8 s_llroundf-ppc64 \
 			e_expf-power8 e_expf-ppc64 \
 			s_sinf-ppc64 s_sinf-power8 \
-			s_cosf-ppc64 s_cosf-power8
+			s_cosf-ppc64 s_cosf-power8 \
+			slowpow-power7 slowpow-power8 slowpow-power9 slowpow-ppc64 \
+			e_pow-power7 e_pow-power8 e_pow-power9 e_pow-ppc64 \
+			slowexp-power7 slowexp-power8 slowexp-power9 slowexp-ppc64 \
+			e_exp-power7 e_exp-power8 e_exp-power9 e_exp-ppc64
 
 CFLAGS-s_logbf-power7.c = -mcpu=power7
 CFLAGS-s_logbl-power7.c = -mcpu=power7
@@ -36,6 +40,18 @@  CFLAGS-s_modf-power5+.c = -mcpu=power5+
 CFLAGS-s_modff-power5+.c = -mcpu=power5+
 CFLAGS-e_hypot-power7.c = -mcpu=power7
 CFLAGS-e_hypotf-power7.c = -mcpu=power7
+CFLAGS-slowpow-power7.c = -mcpu=power7
+CFLAGS-slowpow-power8.c = -mcpu=power8
+CFLAGS-slowpow-power9.c = -mcpu=power9
+CFLAGS-e_pow-power7.c = -mcpu=power7
+CFLAGS-e_pow-power8.c = -mcpu=power8
+CFLAGS-e_pow-power9.c = -mcpu=power9
+CFLAGS-slowexp-power7.c = -mcpu=power7
+CFLAGS-slowexp-power8.c = -mcpu=power8
+CFLAGS-slowexp-power9.c = -mcpu=power9
+CFLAGS-e_exp-power7.c = -mcpu=power7
+CFLAGS-e_exp-power8.c = -mcpu=power8
+CFLAGS-e_exp-power9.c = -mcpu=power9
 
 # These files quiet sNaNs in a way that is optimized away without
 # -fsignaling-nans.
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-power7.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-power7.c
new file mode 100644
index 0000000000..652b2ec862
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-power7.c
@@ -0,0 +1,28 @@ 
+/* __ieee_exp() POWER7 version.
+   Copyright (C) 2017 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/>.  */
+
+
+#undef strong_alias
+#define strong_alias(a, b)
+
+#define __ieee754_exp __ieee754_exp_power7
+#define __exp1 __exp1_power7
+#define __slowexp __slowexp_power7
+#define SECTION __attribute__ ((section (".text.power7")))
+
+#include <sysdeps/ieee754/dbl-64/e_exp.c>
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-power8.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-power8.c
new file mode 100644
index 0000000000..c9561e462b
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-power8.c
@@ -0,0 +1,28 @@ 
+/* __ieee_exp() POWER8 version.
+   Copyright (C) 2017 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/>.  */
+
+
+#undef strong_alias
+#define strong_alias(a, b)
+
+#define __ieee754_exp __ieee754_exp_power8
+#define __exp1 __exp1_power8
+#define __slowexp __slowexp_power8
+#define SECTION __attribute__ ((section (".text.power8")))
+
+#include <sysdeps/ieee754/dbl-64/e_exp.c>
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-power9.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-power9.c
new file mode 100644
index 0000000000..a4f2a8890c
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-power9.c
@@ -0,0 +1,28 @@ 
+/* __ieee_exp() POWER9 version.
+   Copyright (C) 2017 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/>.  */
+
+
+#undef strong_alias
+#define strong_alias(a, b)
+
+#define __ieee754_exp __ieee754_exp_power9
+#define __exp1 __exp1_power9
+#define __slowexp __slowexp_power9
+#define SECTION __attribute__ ((section (".text.power9")))
+
+#include <sysdeps/ieee754/dbl-64/e_exp.c>
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-ppc64.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-ppc64.c
new file mode 100644
index 0000000000..8d65aaa895
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp-ppc64.c
@@ -0,0 +1,26 @@ 
+/* __ieee_pow() PowerPC64 version.
+   Copyright (C) 2017 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/>.  */
+
+#undef strong_alias
+#define strong_alias(a, b)
+
+#define __ieee754_exp __ieee754_exp_ppc64
+#define __exp1 __exp1_ppc64
+#define __slowexp __slowexp_ppc64
+
+#include <sysdeps/ieee754/dbl-64/e_exp.c>
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp.c
new file mode 100644
index 0000000000..10bfa09e71
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_exp.c
@@ -0,0 +1,37 @@ 
+/* Multiple versions of ieee754_exp.
+   Copyright (C) 2017 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 <math_ldbl_opt.h>
+#include "init-arch.h"
+
+extern __typeof (__ieee754_exp) __ieee754_exp_ppc64 attribute_hidden;
+extern __typeof (__ieee754_exp) __ieee754_exp_power7 attribute_hidden;
+extern __typeof (__ieee754_exp) __ieee754_exp_power8 attribute_hidden;
+extern __typeof (__ieee754_exp) __ieee754_exp_power9 attribute_hidden;
+
+libc_ifunc (__ieee754_exp,
+      (hwcap2 & PPC_FEATURE2_ARCH_3_00)
+      ? __ieee754_exp_power9
+      : (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+        ? __ieee754_exp_power8
+        : (hwcap & PPC_FEATURE_ARCH_2_06)
+          ? __ieee754_exp_power7
+          : __ieee754_exp_ppc64);
+
+strong_alias (__ieee754_exp, __exp_finite)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-power7.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-power7.c
new file mode 100644
index 0000000000..e0a69396c6
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-power7.c
@@ -0,0 +1,28 @@ 
+/* __ieee_pow() POWER7 version.
+   Copyright (C) 2017 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/>.  */
+
+
+#undef strong_alias
+#define strong_alias(a, b)
+
+#define __ieee754_pow __ieee754_pow_power7
+#define __exp1 __exp1_power7
+#define __slowpow __slowpow_power7
+#define SECTION __attribute__ ((section (".text.power7")))
+
+#include <sysdeps/ieee754/dbl-64/e_pow.c>
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-power8.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-power8.c
new file mode 100644
index 0000000000..4ecff81505
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-power8.c
@@ -0,0 +1,28 @@ 
+/* __ieee_pow() POWER8 version.
+   Copyright (C) 2017 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/>.  */
+
+
+#undef strong_alias
+#define strong_alias(a, b)
+
+#define __ieee754_pow __ieee754_pow_power8
+#define __exp1 __exp1_power8
+#define __slowpow __slowpow_power8
+#define SECTION __attribute__ ((section (".text.power8")))
+
+#include <sysdeps/ieee754/dbl-64/e_pow.c>
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-power9.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-power9.c
new file mode 100644
index 0000000000..a674a26759
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-power9.c
@@ -0,0 +1,28 @@ 
+/* __ieee_pow() POWER9 version.
+   Copyright (C) 2017 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/>.  */
+
+
+#undef strong_alias
+#define strong_alias(a, b)
+
+#define __ieee754_pow __ieee754_pow_power9
+#define __exp1 __exp1_power9
+#define __slowpow __slowpow_power9
+#define SECTION __attribute__ ((section (".text.power9")))
+
+#include <sysdeps/ieee754/dbl-64/e_pow.c>
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-ppc64.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-ppc64.c
new file mode 100644
index 0000000000..1efcde2780
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow-ppc64.c
@@ -0,0 +1,26 @@ 
+/* __ieee_pow() PowerPC64 version.
+   Copyright (C) 2017 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/>.  */
+
+#undef strong_alias
+#define strong_alias(a, b)
+
+#define __ieee754_pow __ieee754_pow_ppc64
+#define __exp1 __exp1_ppc64
+#define __slowpow __slowpow_ppc64
+
+#include <sysdeps/ieee754/dbl-64/e_pow.c>
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow.c
new file mode 100644
index 0000000000..c46c21ccf4
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_pow.c
@@ -0,0 +1,37 @@ 
+/* Multiple versions of ieee754_pow.
+   Copyright (C) 2017 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 <math_ldbl_opt.h>
+#include "init-arch.h"
+
+extern __typeof (__ieee754_pow) __ieee754_pow_ppc64 attribute_hidden;
+extern __typeof (__ieee754_pow) __ieee754_pow_power7 attribute_hidden;
+extern __typeof (__ieee754_pow) __ieee754_pow_power8 attribute_hidden;
+extern __typeof (__ieee754_pow) __ieee754_pow_power9 attribute_hidden;
+
+libc_ifunc (__ieee754_pow,
+      (hwcap2 & PPC_FEATURE2_ARCH_3_00)
+      ? __ieee754_pow_power9
+      : (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+        ? __ieee754_pow_power8
+        : (hwcap & PPC_FEATURE_ARCH_2_06)
+          ? __ieee754_pow_power7
+          : __ieee754_pow_ppc64);
+
+strong_alias (__ieee754_pow, __pow_finite)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/slowexp-power7.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/slowexp-power7.c
new file mode 100644
index 0000000000..ae874d0ce9
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/slowexp-power7.c
@@ -0,0 +1,26 @@ 
+/* __slowexp() POWER7 version.
+   Copyright (C) 2017 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/>.  */
+
+
+#undef strong_alias
+#define strong_alias(a, b)
+
+#define __slowexp __slowexp_power7
+#define SECTION __attribute__ ((section (".text.power7")))
+
+#include <sysdeps/ieee754/dbl-64/slowexp.c>
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/slowexp-power8.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/slowexp-power8.c
new file mode 100644
index 0000000000..d53d60e9e6
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/slowexp-power8.c
@@ -0,0 +1,26 @@ 
+/* __slowexp() POWER8 version.
+   Copyright (C) 2017 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/>.  */
+
+
+#undef strong_alias
+#define strong_alias(a, b)
+
+#define __slowexp __slowexp_power8
+#define SECTION __attribute__ ((section (".text.power8")))
+
+#include <sysdeps/ieee754/dbl-64/slowexp.c>
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/slowexp-power9.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/slowexp-power9.c
new file mode 100644
index 0000000000..5bdc26539a
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/slowexp-power9.c
@@ -0,0 +1,26 @@ 
+/* __slowexp() POWER9 version.
+   Copyright (C) 2017 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/>.  */
+
+
+#undef strong_alias
+#define strong_alias(a, b)
+
+#define __slowexp __slowexp_power9
+#define SECTION __attribute__ ((section (".text.power9")))
+
+#include <sysdeps/ieee754/dbl-64/slowexp.c>
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/slowexp-ppc64.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/slowexp-ppc64.c
new file mode 100644
index 0000000000..6479eff5ea
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/slowexp-ppc64.c
@@ -0,0 +1,24 @@ 
+/* __slowexp() PowerPC64 version.
+   Copyright (C) 2017 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/>.  */
+
+#undef strong_alias
+#define strong_alias(a, b)
+
+#define __slowexp __slowexp_ppc64
+
+#include <sysdeps/ieee754/dbl-64/slowexp.c>
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-power7.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-power7.c
new file mode 100644
index 0000000000..de6baaaf14
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-power7.c
@@ -0,0 +1,26 @@ 
+/* __slowpow() POWER7 version.
+   Copyright (C) 2017 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/>.  */
+
+
+#undef strong_alias
+#define strong_alias(a, b)
+
+#define __slowpow __slowpow_power7
+#define SECTION __attribute__ ((section (".text.power7")))
+
+#include <sysdeps/ieee754/dbl-64/slowpow.c>
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-power8.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-power8.c
new file mode 100644
index 0000000000..8c42bd93ff
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-power8.c
@@ -0,0 +1,26 @@ 
+/* __slowpow() POWER8 version.
+   Copyright (C) 2017 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/>.  */
+
+
+#undef strong_alias
+#define strong_alias(a, b)
+
+#define __slowpow __slowpow_power8
+#define SECTION __attribute__ ((section (".text.power8")))
+
+#include <sysdeps/ieee754/dbl-64/slowpow.c>
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-power9.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-power9.c
new file mode 100644
index 0000000000..05baef3939
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-power9.c
@@ -0,0 +1,26 @@ 
+/* __slowpow() POWER9 version.
+   Copyright (C) 2017 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/>.  */
+
+
+#undef strong_alias
+#define strong_alias(a, b)
+
+#define __slowpow __slowpow_power9
+#define SECTION __attribute__ ((section (".text.power9")))
+
+#include <sysdeps/ieee754/dbl-64/slowpow.c>
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-ppc64.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-ppc64.c
new file mode 100644
index 0000000000..3fdac58455
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/slowpow-ppc64.c
@@ -0,0 +1,24 @@ 
+/* __slowpow() PowerPC64 version.
+   Copyright (C) 2017 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/>.  */
+
+#undef strong_alias
+#define strong_alias(a, b)
+
+#define __slowpow __slowpow_ppc64
+
+#include <sysdeps/ieee754/dbl-64/slowpow.c>