diff mbox

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

Message ID 20170713215607.GA16165@ibm-tiger.the-meissners.org
State New
Headers show

Commit Message

Michael Meissner July 13, 2017, 9:56 p.m. UTC
On Thu, Jul 13, 2017 at 03:57:08PM -0500, Segher Boessenkool wrote:
> 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?)

I have patches for both 6 and 7.  I had to back port the change in
testsuite/lib/target-supports.exp for ppc_cpu_supports_hw_available in order to
add the dg-requires for the 1 test that is in the testsuite.

The part of the change that changed the target_clones warning to error is not
appropriate for either branch, and that patch has been dropped.  The GCC 6
patch for defining __BUILTIN_CPU_SUPPORTS__ had to be moved since the
preceeding lines aren't in GCC 6.

Given we have the macro __BUILTIN_CPU_SUPPORTS__, I could change the test to
use that instead of a dg-requires and drop ppc_cpu_supports_hw_available.

Comments

Segher Boessenkool July 13, 2017, 10:58 p.m. UTC | #1
On Thu, Jul 13, 2017 at 05:56:07PM -0400, Michael Meissner wrote:
> Given we have the macro __BUILTIN_CPU_SUPPORTS__, I could change the test to
> use that instead of a dg-requires and drop ppc_cpu_supports_hw_available.

Ah that would be nice, good idea!


Segher
diff mbox

Patch

Index: gcc/config/rs6000/rs6000-c.c
===================================================================
--- gcc/config/rs6000/rs6000-c.c	(revision 250169)
+++ gcc/config/rs6000/rs6000-c.c	(working copy)
@@ -648,6 +648,9 @@  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__");
+#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	(revision 250169)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -15584,6 +15584,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
@@ -15591,6 +15593,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 */
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi	(revision 250169)
+++ gcc/doc/extend.texi	(working copy)
@@ -14894,10 +14894,25 @@  This function is a @code{nop} on the Pow
 to maintain API compatibility with the x86 builtins.
 @end deftypefn
 
+@deftypefn {Built-in Function} void __builtin_cpu_init (void)
+This function is a @code{nop} on the PowerPC platform and is included solely
+to maintain API compatibility with the x86 builtins.
+@end deftypefn
+
 @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
+which exports the hardware capability bits.  GCC defines the macro
+@code{__BUILTIN_CPU_SUPPORTS__} if the @code{__builtin_cpu_supports}
+built-in function is fully supported.
+
+If GCC was configured to use a GLIBC before 2.23, the built-in
+function @code{__builtin_cpu_is} always returns a 0 and the compiler
+issues a warning.
+
+The following CPU names can be detected:
 
 @table @samp
 @item power9
@@ -14934,20 +14949,33 @@  IBM PowerPC Cell Broadband Engine Archit
 
 Here is an example:
 @smallexample
-if (__builtin_cpu_is ("power8"))
-  @{
-     do_power8 (); // POWER8 specific implementation.
-  @}
-else
-  @{
-     do_generic (); // Generic implementation.
-  @}
+#ifdef __BUILTIN_CPU_SUPPORTS__
+  if (__builtin_cpu_is ("power8"))
+    @{
+       do_power8 (); // POWER8 specific implementation.
+    @}
+  else
+#endif
+    @{
+       do_generic (); // Generic implementation.
+    @}
 @end smallexample
 @end deftypefn
 
 @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 which exports the hardware capability bits.  GCC defines the
+macro @code{__BUILTIN_CPU_SUPPORTS__} if the
+@code{__builtin_cpu_supports} built-in function is fully supported.
+
+If GCC was configured to use a GLIBC before 2.23, the built-in
+function @code{__builtin_cpu_suports} always returns a 0 and the
+compiler issues a warning.
+
+The following features can be
 detected:
 
 @table @samp
@@ -15031,14 +15059,16 @@  CPU supports the vector-scalar extension
 
 Here is an example:
 @smallexample
-if (__builtin_cpu_supports ("fpu"))
-  @{
-     asm("fadd %0,%1,%2" : "=d"(dst) : "d"(src1), "d"(src2));
-  @}
-else
-  @{
-     dst = __fadd (src1, src2); // Software FP addition function.
-  @}
+#ifdef __BUILTIN_CPU_SUPPORTS__
+  if (__builtin_cpu_supports ("fpu"))
+    @{
+       asm("fadd %0,%1,%2" : "=d"(dst) : "d"(src1), "d"(src2));
+    @}
+  else
+#endif
+    @{
+       dst = __fadd (src1, src2); // Software FP addition function.
+    @}
 @end smallexample
 @end deftypefn
 
Index: gcc/testsuite/lib/target-supports.exp
===================================================================
--- gcc/testsuite/lib/target-supports.exp	(revision 250169)
+++ gcc/testsuite/lib/target-supports.exp	(working copy)
@@ -1896,6 +1896,37 @@  proc check_effective_target_powerpc64_no
 	} {-O2}]
 }
 
+# Return 1 if the target supports the __builtin_cpu_supports built-in,
+# including having a new enough library to support the test.  Cache the result.
+# Require at least a power7 to run on.
+
+proc check_ppc_cpu_supports_hw_available { } {
+    return [check_cached_effective_target ppc_cpu_supports_hw_available {
+	# Some simulators are known to not support VSX/power8 instructions.
+	# For now, disable on Darwin
+	if { [istarget powerpc-*-eabi]
+	     || [istarget powerpc*-*-eabispe]
+	     || [istarget *-*-darwin*]} {
+	    expr 0
+	} else {
+	    set options "-mvsx"
+	    check_runtime_nocache ppc_cpu_supports_hw_available {
+		int main()
+		{
+		#ifdef __MACH__
+		  asm volatile ("xxlor vs0,vs0,vs0");
+		#else
+		  asm volatile ("xxlor 0,0,0");
+	        #endif
+		  if (!__builtin_cpu_supports ("vsx"))
+		    return 1;
+		  return 0;
+		}
+	    } $options
+	}
+    }]
+}
+
 # Return 1 if the target supports executing power8 vector instructions, 0
 # otherwise.  Cache the result.
 
Index: gcc/testsuite/gcc.target/powerpc/cpu-builtin-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/cpu-builtin-1.c	(revision 250169)
+++ gcc/testsuite/gcc.target/powerpc/cpu-builtin-1.c	(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)