diff mbox

, PR target/81193, Add warning for using __builtin_cpu_* on old PowerPC GLIBC's

Message ID 20170712153811.GA29175@ibm-tiger.the-meissners.org
State New
Headers show

Commit Message

Michael Meissner July 12, 2017, 3:38 p.m. UTC
This patch adds a warning to the built-in function handling if the user used
the __builtin_cpu_supports and __builtin_cpu_is were used when the compiler was
configured to use an old GLIBC that does not provice the hardware capability
bits.  Previously, the compiler would silently change the built-in function to
return 0.

I also changed the current warning in target_clones handling to be an error
instead of a warning, since it really makes no sense to use target_clones if we
can't generate a resolver function.

To allow people to figure out whether the built-in functions __builtin_cpu_is
and __builtin_cpu_supports are supported, I added the following defines if you
are using a new glibc:

	__BUILTIN_CPU_IS__
	__BUILTIN_CPU_SUPPORTS__

I added documentation to state the requirement for using a new GLIBC.

I went through the testsuite and added the appropriate target requires for the
tests that require __builtin_cpu_supports (cpu support test and the bmi*
tests).

I changed the libgcc build so that the IEEE float128 ifunc support function
(float128-ifunc.c) is only built if GCC is configured to use a new GLIBC.  I
verified that if you build with a compiler configured to use an old GCC that it
does not generate the ifunc handlers, and it always uses floating point
emulation.  If you configure GCC to use a new GLIBC, it will generate the ifunc
handler.  I did verify that on a power8 system, it will call the software
emulation, and on a power9 system, it will use the hardware IEEE float128
instructions.

I built boostrap compilers with/without the patches on a little endian power8
system and there were no regressions.

On the little endian power8 system, I did one run using the host Ubuntu
libraries, which are based on GLIBC 2.19.  There were no regressions between a
compiler without the patches and with the patches.  I verified that all of the
tests that use __builtin_cpu_supports are now UNSUPPORTED.

On the same little endian power8 system, I did a second set of runs using the
Advance Toolchain AT-10.4 libraries, which are based on GLIBC 2.24.  There were
no regressions between a compiler without the patches and with the patches.  I
verified that all of the tests that use __builtin_cpu_supports were run and
were successful.

I also did a test with bootstrap on a big endian power7 system with both 32-bit
and 64-bit libraries, there were no regressions.  For this set of runs, I used
the older host libraries, which do not export the hardware capability bits.  I
could not test using the Advance Toolchain on that system, since that
particular system is too old to install the newer Advance Toolchain libraries
that provide the hardware capability bits.

Can I install these patches on the trunk?  After a burn-in period, can I
install equivalent patches to GCC 7 (which added the __builtin_cpu* built-in
functions)?

[gcc]
2017-07-12  Michael Meissner  <meissner@linux.vnet.ibm.com>

	PR target/81193
	* config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): If GLIBC
	provides the hardware capability bits, define __BUILTIN_CPU_IS__
	and __BUILTIN_CPU_SUPPORTS__.
	* config/rs6000/rs6000.c (cpu_expand_builtin): Generate a warning
	if GLIBC does not provide the hardware capability bits.  Add a
	gcc_unreachable call if the built-in cpu function is neither
	__builtin_cpu_is nor __builtin_cpu_supports.
	(rs6000_get_function_versions_dispatcher): Change the warnging
	that an old GLIBC is used which does not export the capability
	bits to be an error.
	* doc/extend.texi (target_clones attribute): Document the
	restriction that GLIBC 2.23 or newer is needed on the PowerPC.
	(PowerPC built-in functions): Document that GLIBC 2.23 or newer is
	needed by __builtin_cpu_is and __builtin_cpu_supports.  Document
	the macros defined by GCC if the newer GLIBC is available.

[gcc/testsuite]
2017-07-12  Michael Meissner  <meissner@linux.vnet.ibm.com>

	PR target/81193
	* gcc.target/powerpc/bmi-andn-1.c: Add guard against using
	__builtin_cpu_supports with old GLIBC's.
	* gcc.target/powerpc/bmi-andn-2.c: Likewise.
	* gcc.target/powerpc/bmi-bextr-1.c: Likewise.
	* gcc.target/powerpc/bmi-bextr-2.c: Likewise.
	* gcc.target/powerpc/bmi-bextr-4.c: Likewise.
	* gcc.target/powerpc/bmi-bextr-5.c: Likewise.
	* gcc.target/powerpc/bmi-blsi-1.c: Likewise.
	* gcc.target/powerpc/bmi-blsi-2.c: Likewise.
	* gcc.target/powerpc/bmi-blsmsk-1.c: Likewise.
	* gcc.target/powerpc/bmi-blsmsk-2.c: Likewise.
	* gcc.target/powerpc/bmi-blsr-1.c: Likewise.
	* gcc.target/powerpc/bmi-blsr-2.c: Likewise.
	* gcc.target/powerpc/bmi-tzcnt-1.c: Likewise.
	* gcc.target/powerpc/bmi-tzcnt-2.c: Likewise.
	* gcc.target/powerpc/bmi2-bzhi32-1.c: Likewise.
	* gcc.target/powerpc/bmi2-bzhi64-1.c: Likewise.
	* gcc.target/powerpc/bmi2-mulx32-1.c: Likewise.
	* gcc.target/powerpc/bmi2-mulx32-2.c: Likewise.
	* gcc.target/powerpc/bmi2-mulx64-1.c: Likewise.
	* gcc.target/powerpc/bmi2-mulx64-2.c: Likewise.
	* gcc.target/powerpc/bmi2-pdep32-1.c: Likewise.
	* gcc.target/powerpc/bmi2-pdep64-1.c: Likewise.
	* gcc.target/powerpc/bmi2-pext32-1.c: Likewise.
	* gcc.target/powerpc/bmi2-pext64-1.c: Likewise.
	* gcc.target/powerpc/cpu-builtin-1.c: Likewise.

[libgcc]
2017-07-12  Michael Meissner  <meissner@linux.vnet.ibm.com>

	PR target/81193
	* configure.ac (PowerPC float128 hardware support): Test whether
	we can use __builtin_cpu_supports before enabling the ifunc
	handler.
	* configure: Regenerate.

Comments

Segher Boessenkool July 12, 2017, 9:07 p.m. UTC | #1
Hi Mike,

On Wed, Jul 12, 2017 at 11:38:11AM -0400, Michael Meissner wrote:
> I also changed the current warning in target_clones handling to be an error
> instead of a warning, since it really makes no sense to use target_clones if we
> can't generate a resolver function.

Okay.  Another option is to then always use the default, but this
certainly is easier; let's hope we can get away with it.

> 	(rs6000_get_function_versions_dispatcher): Change the warnging

Typo.

> --- gcc/config/rs6000/rs6000-c.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000)	(revision 250063)
> +++ gcc/config/rs6000/rs6000-c.c	(.../gcc/config/rs6000)	(working copy)
> @@ -644,6 +644,10 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi
>      builtin_define ("__FLOAT128_HARDWARE__");
>    if (TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (TFmode))
>      builtin_define ("__ibm128=long double");
> +#ifdef TARGET_LIBC_PROVIDES_HWCAP_IN_TCB
> +  builtin_define ("__BUILTIN_CPU_SUPPORTS__");
> +  builtin_define ("__BUILTIN_CPU_IS__");
> +#endif

Is it useful to have two defines?  They always are enabled at the same
time afaics?  Thinking of a good name isn't so easy of course, but maybe
just __BUILTIN_CPU_SUPPORTS__ is fine always.

Or do other architectures already have both?

> +The @code{__builtin_cpu_is} function requires GLIBC 2.23 or newer in
> +order to export the hardware capability bits.  The
> +@code{__builtin_cpu_is} function will return 0 if the compiler was
> +configured for an earlier GCC.  GCC defines the macro
> +@code{__BUILTIN_CPU_IS__} if you can use the @code{__builtin_cpu_is}
> +built-in function.

"if you can use it" is not very clear (the line before you said you
always can use it, it just returns 0).

Okay for trunk and 7 with those things taken care of.  Thanks!


Segher
Michael Meissner July 12, 2017, 9:18 p.m. UTC | #2
On Wed, Jul 12, 2017 at 04:07:42PM -0500, Segher Boessenkool wrote:
> Hi Mike,
> 
> On Wed, Jul 12, 2017 at 11:38:11AM -0400, Michael Meissner wrote:
> > I also changed the current warning in target_clones handling to be an error
> > instead of a warning, since it really makes no sense to use target_clones if we
> > can't generate a resolver function.
> 
> Okay.  Another option is to then always use the default, but this
> certainly is easier; let's hope we can get away with it.

We can always change it, but it needs to make sure the user doesn't get two
warnings then (one for target_clones, and a second one for
__builtin_cpu_supports).

> > 	(rs6000_get_function_versions_dispatcher): Change the warnging
> 
> Typo.

Thanks.

> > --- gcc/config/rs6000/rs6000-c.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000)	(revision 250063)
> > +++ gcc/config/rs6000/rs6000-c.c	(.../gcc/config/rs6000)	(working copy)
> > @@ -644,6 +644,10 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi
> >      builtin_define ("__FLOAT128_HARDWARE__");
> >    if (TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (TFmode))
> >      builtin_define ("__ibm128=long double");
> > +#ifdef TARGET_LIBC_PROVIDES_HWCAP_IN_TCB
> > +  builtin_define ("__BUILTIN_CPU_SUPPORTS__");
> > +  builtin_define ("__BUILTIN_CPU_IS__");
> > +#endif
> 
> Is it useful to have two defines?  They always are enabled at the same
> time afaics?  Thinking of a good name isn't so easy of course, but maybe
> just __BUILTIN_CPU_SUPPORTS__ is fine always.

Yeah, I was wondering about that.  I'll delete __BUILTIN_CPU_IS__, since I find
that to be less useful.

> 
> Or do other architectures already have both?

The only other architecture that supports __builtin_cpu_{init,is,supports} is
the X86, and they don't have the macros.  But then they also don't have the
issue that you can't do a lot in the ifunc resolver.

> > +The @code{__builtin_cpu_is} function requires GLIBC 2.23 or newer in
> > +order to export the hardware capability bits.  The
> > +@code{__builtin_cpu_is} function will return 0 if the compiler was
> > +configured for an earlier GCC.  GCC defines the macro
> > +@code{__BUILTIN_CPU_IS__} if you can use the @code{__builtin_cpu_is}
> > +built-in function.
> 
> "if you can use it" is not very clear (the line before you said you
> always can use it, it just returns 0).

I will reword it.

> Okay for trunk and 7 with those things taken care of.  Thanks!

Thanks.
Michael Meissner July 12, 2017, 11:19 p.m. UTC | #3
Hmmm, I didn't realize that gcc 6.x also supported __builtin_cpu_*.  I imagine
we will need backports there as well.
Segher Boessenkool July 13, 2017, 8:57 p.m. UTC | #4
On Wed, Jul 12, 2017 at 07:19:27PM -0400, Michael Meissner wrote:
> Hmmm, I didn't realize that gcc 6.x also supported __builtin_cpu_*.  I imagine
> we will need backports there as well.

Okay for 6 too if needed there (do testcases warn us for that?)

Thanks,


Segher
diff mbox

Patch

Index: gcc/config/rs6000/rs6000-c.c
===================================================================
--- gcc/config/rs6000/rs6000-c.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000)	(revision 250063)
+++ gcc/config/rs6000/rs6000-c.c	(.../gcc/config/rs6000)	(working copy)
@@ -644,6 +644,10 @@  rs6000_cpu_cpp_builtins (cpp_reader *pfi
     builtin_define ("__FLOAT128_HARDWARE__");
   if (TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (TFmode))
     builtin_define ("__ibm128=long double");
+#ifdef TARGET_LIBC_PROVIDES_HWCAP_IN_TCB
+  builtin_define ("__BUILTIN_CPU_SUPPORTS__");
+  builtin_define ("__BUILTIN_CPU_IS__");
+#endif
 
   /* We needed to create a keyword if -mfloat128-type was used but not -mfloat,
      so we used __ieee128.  If -mfloat128 was used, create a #define back to
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000)	(revision 250063)
+++ gcc/config/rs6000/rs6000.c	(.../gcc/config/rs6000)	(working copy)
@@ -15176,6 +15176,8 @@  cpu_expand_builtin (enum rs6000_builtins
       emit_insn (gen_eqsi3 (scratch2, scratch1, const0_rtx));
       emit_insn (gen_rtx_SET (target, gen_rtx_XOR (SImode, scratch2, const1_rtx)));
     }
+  else
+    gcc_unreachable ();
 
   /* Record that we have expanded a CPU builtin, so that we can later
      emit a reference to the special symbol exported by LIBC to ensure we
@@ -15183,6 +15185,9 @@  cpu_expand_builtin (enum rs6000_builtins
   cpu_builtin_p = true;
 
 #else
+  warning (0, "%s needs GLIBC (2.23 and newer) that exports hardware "
+	   "capability bits", rs6000_builtin_info[(size_t) fcode].name);
+  
   /* For old LIBCs, always return FALSE.  */
   emit_move_insn (target, GEN_INT (0));
 #endif /* TARGET_LIBC_PROVIDES_HWCAP_IN_TCB */
@@ -37284,10 +37289,10 @@  rs6000_get_function_versions_dispatcher 
   default_node = default_version_info->this_node;
 
 #ifndef TARGET_LIBC_PROVIDES_HWCAP_IN_TCB
-  warning_at (DECL_SOURCE_LOCATION (default_node->decl), 0,
-	      "target_clone needs GLIBC (2.23 and newer) to export hardware "
-	      "capability bits");
-#endif
+  error_at (DECL_SOURCE_LOCATION (default_node->decl),
+	    "target_clones attribute needs GLIBC (2.23 and newer) that "
+	    "exports hardware capability bits");
+#else
 
   if (targetm.has_ifunc_p ())
     {
@@ -37320,6 +37325,7 @@  rs6000_get_function_versions_dispatcher 
 		"multiversioning needs ifunc which is not supported "
 		"on this target");
     }
+#endif
 
   return dispatch_decl;
 }
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/doc)	(revision 250063)
+++ gcc/doc/extend.texi	(.../gcc/doc)	(working copy)
@@ -3282,7 +3282,9 @@  one compiled with @option{-msse4.1} and 
 On a PowerPC, you can compile a function with
 @code{target_clones("cpu=power9,default")}.  GCC will create two
 function clones, one compiled with @option{-mcpu=power9} and another
-with the default options.
+with the default options.  On the PowerPC, the compiler must be
+configured to use GLIBC 2.23 or newer in order to use the
+@code{target_clones} attribute.
 
 It also creates a resolver function (see
 the @code{ifunc} attribute above) that dynamically selects a clone
@@ -14918,8 +14920,16 @@  to maintain API compatibility with the x
 
 @deftypefn {Built-in Function} int __builtin_cpu_is (const char *@var{cpuname})
 This function returns a value of @code{1} if the run-time CPU is of type
-@var{cpuname} and returns @code{0} otherwise. The following CPU names can be
-detected:
+@var{cpuname} and returns @code{0} otherwise
+
+The @code{__builtin_cpu_is} function requires GLIBC 2.23 or newer in
+order to export the hardware capability bits.  The
+@code{__builtin_cpu_is} function will return 0 if the compiler was
+configured for an earlier GCC.  GCC defines the macro
+@code{__BUILTIN_CPU_IS__} if you can use the @code{__builtin_cpu_is}
+built-in function.
+
+The following CPU names can be detected:
 
 @table @samp
 @item power9
@@ -14969,7 +14979,16 @@  else
 
 @deftypefn {Built-in Function} int __builtin_cpu_supports (const char *@var{feature})
 This function returns a value of @code{1} if the run-time CPU supports the HWCAP
-feature @var{feature} and returns @code{0} otherwise. The following features can be
+feature @var{feature} and returns @code{0} otherwise.
+
+The @code{__builtin_cpu_supports} function requires GLIBC 2.23 or newer in
+order to export the hardware capability bits.  The
+@code{__builtin_cpu_supports} function will return 0 if the compiler was
+configured for an earlier GCC.  GCC defines the macro
+@code{__BUILTIN_CPU_SUPPORTS__} if you can use the @code{__builtin_cpu_supports}
+built-in function.
+
+The following features can be
 detected:
 
 @table @samp
Index: gcc/testsuite/gcc.target/powerpc/bmi-blsi-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bmi-blsi-1.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/bmi-blsi-1.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -1,6 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O3 -fno-inline" } */
 /* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 #define NO_WARN_X86_INTRINSICS 1
 #include <x86intrin.h>
Index: gcc/testsuite/gcc.target/powerpc/bmi-bextr-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bmi-bextr-2.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/bmi-bextr-2.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -1,6 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O3 -fno-inline" } */
 /* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 #define NO_WARN_X86_INTRINSICS 1
 #include <x86intrin.h>
Index: gcc/testsuite/gcc.target/powerpc/bmi2-bzhi64-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bmi2-bzhi64-1.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/bmi2-bzhi64-1.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -1,6 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O3" } */
 /* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 #define NO_WARN_X86_INTRINSICS 1
 #include <x86intrin.h>
Index: gcc/testsuite/gcc.target/powerpc/bmi-blsi-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bmi-blsi-2.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/bmi-blsi-2.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -1,6 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O3 -fno-inline" } */
 /* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 #define NO_WARN_X86_INTRINSICS 1
 #include <x86intrin.h>
Index: gcc/testsuite/gcc.target/powerpc/bmi-blsr-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bmi-blsr-1.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/bmi-blsr-1.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -1,6 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O3 -fno-inline" } */
 /* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 #define NO_WARN_X86_INTRINSICS 1
 #include <x86intrin.h>
Index: gcc/testsuite/gcc.target/powerpc/bmi2-pdep64-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bmi2-pdep64-1.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/bmi2-pdep64-1.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -3,6 +3,7 @@ 
 /* { dg-require-effective-target lp64 } */
 /* { dg-require-effective-target vsx_hw } */
 /* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 #define NO_WARN_X86_INTRINSICS 1
 #include <x86intrin.h>
Index: gcc/testsuite/gcc.target/powerpc/bmi-bextr-4.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bmi-bextr-4.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/bmi-bextr-4.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -1,6 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O3 -fno-inline" } */
 /* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 #define NO_WARN_X86_INTRINSICS 1
 #include <x86intrin.h>
Index: gcc/testsuite/gcc.target/powerpc/bmi-blsr-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bmi-blsr-2.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/bmi-blsr-2.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -1,6 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O3 -fno-inline" } */
 /* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 #define NO_WARN_X86_INTRINSICS 1
 #include <x86intrin.h>
Index: gcc/testsuite/gcc.target/powerpc/bmi-bextr-5.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bmi-bextr-5.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/bmi-bextr-5.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -1,6 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O3 -fno-inline" } */
 /* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 #define NO_WARN_X86_INTRINSICS 1
 #include <x86intrin.h>
Index: gcc/testsuite/gcc.target/powerpc/bmi-blsmsk-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bmi-blsmsk-1.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/bmi-blsmsk-1.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -1,6 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O3 -fno-inline" } */
 /* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 #define NO_WARN_X86_INTRINSICS 1
 #include <x86intrin.h>
Index: gcc/testsuite/gcc.target/powerpc/bmi-blsmsk-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bmi-blsmsk-2.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/bmi-blsmsk-2.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -1,6 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O3 -fno-inline" } */
 /* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 #define NO_WARN_X86_INTRINSICS 1
 #include <x86intrin.h>
Index: gcc/testsuite/gcc.target/powerpc/bmi2-pext64-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bmi2-pext64-1.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/bmi2-pext64-1.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -3,6 +3,7 @@ 
 /* { dg-require-effective-target lp64 } */
 /* { dg-require-effective-target vsx_hw } */
 /* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 #define NO_WARN_X86_INTRINSICS 1
 #include <x86intrin.h>
Index: gcc/testsuite/gcc.target/powerpc/bmi2-bzhi32-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bmi2-bzhi32-1.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/bmi2-bzhi32-1.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -1,6 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O3" } */
 /* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 #define NO_WARN_X86_INTRINSICS 1
 #include <x86intrin.h>
Index: gcc/testsuite/gcc.target/powerpc/bmi2-pdep32-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bmi2-pdep32-1.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/bmi2-pdep32-1.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -3,6 +3,7 @@ 
 /* { dg-require-effective-target lp64 } */
 /* { dg-require-effective-target vsx_hw } */
 /* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 #define NO_WARN_X86_INTRINSICS 1
 #include <x86intrin.h>
Index: gcc/testsuite/gcc.target/powerpc/bmi-andn-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bmi-andn-1.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/bmi-andn-1.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -1,6 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O3" } */
 /* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 #define NO_WARN_X86_INTRINSICS 1
 #include <x86intrin.h>
Index: gcc/testsuite/gcc.target/powerpc/bmi-tzcnt-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bmi-tzcnt-1.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/bmi-tzcnt-1.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -1,6 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O3 -fno-inline" } */
 /* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 #define NO_WARN_X86_INTRINSICS 1
 #include <x86intrin.h>
Index: gcc/testsuite/gcc.target/powerpc/bmi-andn-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bmi-andn-2.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/bmi-andn-2.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -1,6 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O3" } */
 /* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 #define NO_WARN_X86_INTRINSICS 1
 #include <x86intrin.h>
Index: gcc/testsuite/gcc.target/powerpc/cpu-builtin-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/cpu-builtin-1.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/cpu-builtin-1.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -1,5 +1,6 @@ 
 /* { dg-do compile { target { powerpc*-*-* } } } */
 /* { dg-skip-if "" { powerpc*-*-darwin* } } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 void
 use_cpu_is_builtins (unsigned int *p)
Index: gcc/testsuite/gcc.target/powerpc/bmi-tzcnt-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bmi-tzcnt-2.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/bmi-tzcnt-2.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -1,6 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O3 -fno-inline" } */
 /* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 #define NO_WARN_X86_INTRINSICS 1
 #include <x86intrin.h>
Index: gcc/testsuite/gcc.target/powerpc/bmi2-pext32-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bmi2-pext32-1.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/bmi2-pext32-1.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -3,6 +3,7 @@ 
 /* { dg-require-effective-target lp64 } */
 /* { dg-require-effective-target vsx_hw } */
 /* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 #define NO_WARN_X86_INTRINSICS 1
 #include <x86intrin.h>
Index: gcc/testsuite/gcc.target/powerpc/bmi2-mulx64-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bmi2-mulx64-1.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/bmi2-mulx64-1.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -1,6 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O3" } */
 /* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 #define NO_WARN_X86_INTRINSICS 1
 #include "bmi2-check.h"
Index: gcc/testsuite/gcc.target/powerpc/bmi2-mulx64-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bmi2-mulx64-2.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/bmi2-mulx64-2.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -1,6 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O3" } */
 /* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 #define NO_WARN_X86_INTRINSICS 1
 #include <x86intrin.h>
Index: gcc/testsuite/gcc.target/powerpc/bmi2-mulx32-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bmi2-mulx32-1.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/bmi2-mulx32-1.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -1,6 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O3" } */
 /* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 #define NO_WARN_X86_INTRINSICS 1
 #include "bmi2-check.h"
Index: gcc/testsuite/gcc.target/powerpc/bmi2-mulx32-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bmi2-mulx32-2.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/bmi2-mulx32-2.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -1,6 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O3" } */
 /* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 #define NO_WARN_X86_INTRINSICS 1
 #include <x86intrin.h>
Index: gcc/testsuite/gcc.target/powerpc/bmi-bextr-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bmi-bextr-1.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/testsuite/gcc.target/powerpc)	(revision 250063)
+++ gcc/testsuite/gcc.target/powerpc/bmi-bextr-1.c	(.../gcc/testsuite/gcc.target/powerpc)	(working copy)
@@ -1,6 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -fno-inline" } */
 /* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target ppc_cpu_supports_hw } */
 
 #define NO_WARN_X86_INTRINSICS 1
 #include <x86intrin.h>
Index: libgcc/configure.ac
===================================================================
--- libgcc/configure.ac	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/libgcc)	(revision 250063)
+++ libgcc/configure.ac	(.../libgcc)	(working copy)
@@ -376,10 +376,10 @@  esac
 esac
 
 case ${host} in
-# At present, we cannot turn -mfloat128 on via #pragma GCC target,
-# so just check if we have VSX (ISA 2.06) support to build the
-# software libraries, and whether the assembler can handle xsaddqp
-# for hardware support.
+# At present, we cannot turn -mfloat128 on via #pragma GCC target, so just
+# check if we have VSX (ISA 2.06) support to build the software libraries, and
+# whether the assembler can handle xsaddqp for hardware support.  Also check if
+# a new glibc is being used so that __builtin_cpu_supports can be used.
 powerpc*-*-linux*)
   saved_CFLAGS="$CFLAGS"
   CFLAGS="$CFLAGS -mabi=altivec -mvsx -mfloat128"
@@ -398,6 +398,9 @@  powerpc*-*-linux*)
      #ifndef AT_PLATFORM
      #error "AT_PLATFORM is not defined"
      #endif
+     #ifndef __BUILTIN_CPU_SUPPORTS__
+     #error "__builtin_cpu_supports is not available"
+     #endif
      vector unsigned char add (vector unsigned char a, vector unsigned char b)
      {
        vector unsigned char ret;
Index: libgcc/ChangeLog.meissner
===================================================================
--- libgcc/ChangeLog.meissner	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/libgcc)	(revision 0)
+++ libgcc/ChangeLog.meissner	(.../libgcc)	(revision 250138)
@@ -0,0 +1,12 @@ 
+2017-07-11  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+	PR target/81193
+	* configure.ac (PowerPC float128 hardware support): Test whether
+	we can use __builtin_cpu_supports before enabling the ifunc
+	handler.
+	* configure: Regenerate.
+
+2017-07-07   Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+	Clone branch subversion id 250063
+
Index: libgcc/configure
===================================================================
--- libgcc/configure	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/libgcc)	(revision 250063)
+++ libgcc/configure	(.../libgcc)	(working copy)
@@ -4975,10 +4975,10 @@  esac
 esac
 
 case ${host} in
-# At present, we cannot turn -mfloat128 on via #pragma GCC target,
-# so just check if we have VSX (ISA 2.06) support to build the
-# software libraries, and whether the assembler can handle xsaddqp
-# for hardware support.
+# At present, we cannot turn -mfloat128 on via #pragma GCC target, so just
+# check if we have VSX (ISA 2.06) support to build the software libraries, and
+# whether the assembler can handle xsaddqp for hardware support.  Also check if
+# a new glibc is being used so that __builtin_cpu_supports can be used.
 powerpc*-*-linux*)
   saved_CFLAGS="$CFLAGS"
   CFLAGS="$CFLAGS -mabi=altivec -mvsx -mfloat128"
@@ -5013,6 +5013,9 @@  else
      #ifndef AT_PLATFORM
      #error "AT_PLATFORM is not defined"
      #endif
+     #ifndef __BUILTIN_CPU_SUPPORTS__
+     #error "__builtin_cpu_supports is not available"
+     #endif
      vector unsigned char add (vector unsigned char a, vector unsigned char b)
      {
        vector unsigned char ret;