[PATCH v2,rs6000] PR78056: Finish fixing build failure on Power7

Kelvin Nilsen kdnilsen@linux.vnet.ibm.com
Sat Dec 17 08:19:00 GMT 2016


This patch adds warning messages and test cases to an initial patch
already submitted and committed to the trunk on October 26, 2016.  The
earlier patch disables initialization of built-in functions which depend
on assembler capabilities that are not supported by the associated tool
chain.

The original patch was submitted before the work was considered
complete because it was desired to expedite a fix to allow builds on
Power7.  At the time the original patch was submitted for approval, the
following additional tasks were planned.

1. Fail with an assertion error instead of an internal compiler error
if built-in functions are ever defined for which the corresponding
instruction pattern is not supported by the current compiler
configuration.

2. Issue a warning message whenever a command-line -mcpu=XXX request
seeks to configure support for a CPU version which is not supported by
the accompanying assembler.

Besides addressing the above tasks, this new patch also adds a number
of tests to exercise different target configurations.

This second version of the patch differs from the first revision
(which had been sent for review on Dec. 9) in the following ways:

1. Removed #define directives from rs6000.c which were defining
HAVE_AS_POWER9, HAVE_AS_POWER8, HAVE_AS_POPCNTD, HAVE_AS_DFP, and
HAVE_AS_POPCNTB macros.  Rewrote the code that made use of these
macros to be conditioned on #ifdef.

2. Removed redundant parentheses in an expression that defines
the value of the default_cpu variable.

3. Replaced multiple occurrences of (d->icode > 0) with
(d->icode != CODE_FOR_nothing).

4. Replaced two comments which claimed that it is expected
that d->icode equals CODE_FOR_nothing to say instead that
d->icode may equal CODE_FOR_nothing.

5. Added a new effective-target named powerpc_popcntb_ok
and required this effective target in the pr78056-8.c test case.

The patch has been tested with three different tool chains supporting
up to power7, power8, and power9 respectively.  It has successfully
bootstrapped and tested without regressions on
powerpc64le-unknown-linux and powerpc-unknown-linux (big-endian, with
both -m32 and -m64 target options) with no regressions.

Is this patch ok for trunk?

gcc/testsuite/ChangeLog:

2016-12-16  Kelvin Nilsen  <kelvin@gcc.gnu.org>

	PR target/78056
	* gcc.target/powerpc/pr78056-1.c: New test.
	* gcc.target/powerpc/pr78056-2.c: New test.
	* gcc.target/powerpc/pr78056-3.c: New test.
	* gcc.target/powerpc/pr78056-4.c: New test.
	* gcc.target/powerpc/pr78056-5.c: New test.
	* gcc.target/powerpc/pr78056-6.c: New test.
	* gcc.target/powerpc/pr78056-7.c: New test.
	* gcc.target/powerpc/pr78056-8.c: New test.
	* lib/target-supports.exp
	(check_effective_target_powerpc_popcntb_ok): New procedure to test
	whether the effective target supports the popcntb instruction.

gcc/ChangeLog:

2016-12-16  Kelvin Nilsen  <kelvin@gcc.gnu.org>

	PR target/78056
	* doc/sourcebuild.texi (PowerPC-specific attributes): Add
	documentation of the powerpc_popcntb_ok attribute.
	* config/rs6000/rs6000.c (rs6000_option_override_internal): Add
	code to issue warning messages if a requested CPU configuration is
	not supported by the binary (assembler and loader) toolchain.
	(spe_init_builtins): Add two assertions to prevent ICE if attempt is
	made to define a built-in function that has been disabled.
	(paired_init_builtins): Add assertion to prevent ICE if attempt is
	made to define a built-in function that has been disabled.
	(altivec_init_builtins): Add comment explaining why definition
	of the DST built-in functions is not preceded by an assertion
	check.  Add assertions to prevent ICE if attempts are made to
	define an altivec predicate or an abs* built-in function that has
	been disabled.
	(htm_init_builtins): Add comment explaining why definition of the
	htm built-in functions is not preceded by an assertion check.


Index: gcc/doc/sourcebuild.texi
===================================================================
--- gcc/doc/sourcebuild.texi	(revision 241606)
+++ gcc/doc/sourcebuild.texi	(working copy)
@@ -1763,6 +1763,10 @@ PowerPC target supports @code{-mhtm}
 @item powerpc_p8vector_ok
 PowerPC target supports @code{-mpower8-vector}
 
+@item powerpc_popcntb_ok
+PowerPC target supports the @code{popcntb} instruction, indicating
+that this target supports @code{-mcpu=power5}.
+
 @item powerpc_ppu_ok
 PowerPC target supports @code{-mcpu=cell}.
 
Index: gcc/testsuite/gcc.target/powerpc/pr78056-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr78056-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr78056-1.c	(revision 241861)
@@ -0,0 +1,18 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-skip-if "" { powerpc*-*-aix* } } */
+/* { dg-options "-mcpu=power8" } */
+
+/* This test should succeed on both 32- and 64-bit configurations.  */
+#include <altivec.h>
+
+/* Though the command line specifies power8 target, this function is
+   to support power9.  */
+__attribute__((target("cpu=power9")))
+int get_random ()
+{
+  return __builtin_darn_32 ();
+}
+
+/* { dg-final { scan-assembler	   "darn" } } */
Index: gcc/testsuite/gcc.target/powerpc/pr78056-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr78056-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr78056-2.c	(revision 242019)
@@ -0,0 +1,19 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-skip-if "" { powerpc_p9vector_ok } } */
+/* { dg-skip-if "" { powerpc*-*-aix* } } */
+/* { dg-options "-mcpu=power8" } */
+
+/* This test should succeed on both 32- and 64-bit configurations.  */
+#include <altivec.h>
+
+/* Though the command line specifies power8 target, this function is
+   to support power9. Expect an error message here because this target
+   does not support power9.  */
+__attribute__((target("cpu=power9")))
+int get_random ()
+{ /* { dg-warning "lacks power9 support" } */
+  return __builtin_darn_32 (); /* { dg-warning "implicit declaration" } */
+}
+
Index: gcc/testsuite/gcc.target/powerpc/pr78056-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr78056-3.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr78056-3.c	(revision 243613)
@@ -0,0 +1,18 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-skip-if "" { powerpc*-*-aix* } } */
+/* { dg-options "-mcpu=power7" } */
+
+/* This test should succeed on both 32- and 64-bit configurations.  */
+#include <altivec.h>
+
+/* Test for the byte atomic operations on power8 using lbarx/stbcx.  */
+__attribute__((target("cpu=power8")))
+char
+char_fetch_add_relaxed (char *ptr, int value)
+{
+  return __atomic_fetch_add (ptr, value, __ATOMIC_RELAXED);
+}
+
+/* { dg-final { scan-assembler-times "lbarx" 1 } } */
Index: gcc/testsuite/gcc.target/powerpc/pr78056-4.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr78056-4.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr78056-4.c	(revision 243042)
@@ -0,0 +1,20 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */
+/* powerpc_vsx_ok represents power7 */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-skip-if "" { powerpc_p8vector_ok } } */
+/* { dg-skip-if "" { powerpc*-*-aix* } } */
+/* { dg-options "-mcpu=power7" } */
+
+/* This test should succeed on both 32- and 64-bit configurations.  */
+#include <altivec.h>
+
+/* Though the command line specifies power7 target, this function is
+   to support power8, which will fail because this platform does not
+   support power8.  */
+__attribute__((target("cpu=power8")))
+char
+char_fetch_add_relaxed (char *ptr, int value)
+{ /* { dg-warning "lacks power8 support" } */
+  return __atomic_fetch_add (ptr, value, __ATOMIC_RELAXED);
+}
Index: gcc/testsuite/gcc.target/powerpc/pr78056-5.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr78056-5.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr78056-5.c	(revision 243613)
@@ -0,0 +1,17 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power5" } } */
+/* powerpc_vsx_ok represents power7 */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-skip-if "" { powerpc*-*-aix* } } */
+/* { dg-options "-mcpu=power5" } */
+
+/* Though the command line specifies power5 target, this function is
+   to support power7.  */
+__attribute__((target("cpu=power7")))
+int
+div_we (int a, int b)
+{
+  return __builtin_divwe (a, b);
+}
+
+/* { dg-final { scan-assembler-times "divwe "   1 } } */
Index: gcc/testsuite/gcc.target/powerpc/pr78056-6.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr78056-6.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr78056-6.c	(revision 243613)
@@ -0,0 +1,26 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power6" } } */
+/* dfp_hw represents power 6 */
+/* { dg-require-effective-target dfp_hw } */
+/* powerpc_vsx_ok represents power7 */
+/* { dg-skip-if "" { powerpc_vsx_ok } } */
+/* { dg-skip-if "" { powerpc*-*-aix* } } */
+/* { dg-options "-mcpu=power6" } */
+
+/* This test should succeed on both 32- and 64-bit configurations.  */
+#include <altivec.h>
+
+/* This test follows the pattern of pr78056-2.c, which has been
+ * exercised with binutils 2.25.  This test, however, has not
+ * been exercised because the author of the test does not have access
+ * to a development environment that succesfully bootstraps gcc
+ * while at the same lacking assembler support for power 7.  */
+
+/* Though the command line specifies power6 target, this function is
+   to support power7.  */
+__attribute__((target("cpu=power7")))
+int
+div_we (int a, int b)
+{ /* { dg-warning "lacks power7 support" } */
+  return __builtin_divwe (a, b); /* { dg-warning "implicit declaration" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/pr78056-7.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr78056-7.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr78056-7.c	(revision 243613)
@@ -0,0 +1,15 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power5" } } */
+/* dfp_hw represents power 6 */
+/* { dg-require-effective-target dfp_hw } */
+/* { dg-skip-if "" { powerpc*-*-aix* } } */
+/* { dg-options "-mcpu=power5" } */
+
+/* Though the command line specifies power5 target, this function is
+   to support power6.  */
+__attribute__((target("cpu=power6")))
+double power6 (double a, double b)
+{
+  return __builtin_copysign (a, b);
+}
+/* { dg-final { scan-assembler-times "fcpsgn" 1 } } */
Index: gcc/testsuite/gcc.target/powerpc/pr78056-8.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr78056-8.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr78056-8.c	(working copy)
@@ -0,0 +1,26 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power5" } } */
+
+/* powerpc_popcntb_ok represents support for power 5.  */
+/* { dg-require-effective-target powerpc_popcntb_ok } */
+/* dfp_hw represents support for power 6.  */
+/* { dg-skip-if "" { dfp_hw } } */
+/* { dg-skip-if "" { powerpc*-*-aix* } } */
+/* { dg-options "-mcpu=power5" } */
+
+/* This test follows the pattern of pr78056-2.c, which has been
+ * exercised with binutils 2.25.  This test, however, has not
+ * been exercised because the author of the test does not have access
+ * to a development environment that succesfully bootstraps gcc
+ * while at the same lacking assembler support for power 6.  */
+
+/* This test should succeed on both 32- and 64-bit configurations.  */
+/* Though the command line specifies power5 target, this function is
+   to support power6. Expect an error message here because this target
+   does not support power6.  */
+__attribute__((target("cpu=power6")))
+/* fabs/fnabs/fsel */
+double normal1 (double a, double b)
+{ /* { dg-warning "lacks power6 support" } */
+  return __builtin_copysign (a, b); /* { dg-warning "implicit declaration" } */
+}
Index: gcc/testsuite/lib/target-supports.exp
===================================================================
--- gcc/testsuite/lib/target-supports.exp	(revision 241606)
+++ gcc/testsuite/lib/target-supports.exp	(working copy)
@@ -2695,6 +2695,26 @@ proc check_effective_target_dfprt { } {
     }]
 }
 
+proc check_effective_target_powerpc_popcntb_ok { } {
+    return [check_cached_effective_target powerpc_popcntb_ok {
+
+	# Disable on Darwin.
+	if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} {
+	    expr 0
+	} else {
+	    check_runtime_nocache powerpc_popcntb_ok {
+		volatile int r;
+		volatile int a = 0x12345678;
+		int main()
+		{
+		    asm volatile ("popcntb %0,%1" : "=r" (r) : "r" (a));
+		    return 0;
+		}
+	    } "-mcpu=power5"
+	}
+    }]
+}
+
 # Return 1 if the target supports executing DFP hardware instructions,
 # 0 otherwise.  Cache the result.
 
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 241606)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -3860,6 +3860,67 @@ rs6000_option_override_internal (bool global_init_
 
   gcc_assert (cpu_index >= 0);
 
+  if (have_cpu)
+    {
+#ifndef HAVE_AS_POWER9
+      if (processor_target_table[rs6000_cpu_index].processor 
+	  == PROCESSOR_POWER9)
+	{
+	  have_cpu = false;
+	  warning (0, "will not generate power9 instructions because "
+		   "assembler lacks power9 support");
+	}
+#endif
+#ifndef HAVE_AS_POWER8
+      if (processor_target_table[rs6000_cpu_index].processor
+	  == PROCESSOR_POWER8)
+	{
+	  have_cpu = false;
+	  warning (0, "will not generate power8 instructions because "
+		   "assembler lacks power8 support");
+	}
+#endif
+#ifndef HAVE_AS_POPCNTD
+      if (processor_target_table[rs6000_cpu_index].processor
+	  == PROCESSOR_POWER7)
+	{
+	  have_cpu = false;
+	  warning (0, "will not generate power7 instructions because "
+		   "assembler lacks power7 support");
+	}
+#endif
+#ifndef HAVE_AS_DFP
+      if (processor_target_table[rs6000_cpu_index].processor
+	  == PROCESSOR_POWER6)
+	{
+	  have_cpu = false;
+	  warning (0, "will not generate power6 instructions because "
+		   "assembler lacks power6 support");
+	}
+#endif
+#ifndef HAVE_AS_POPCNTB
+      if (processor_target_table[rs6000_cpu_index].processor
+	  == PROCESSOR_POWER5)
+	{
+	  have_cpu = false;
+	  warning (0, "will not generate power5 instructions because "
+		   "assembler lacks power5 support");
+	}
+#endif
+
+      if (!have_cpu)
+	{
+	  /* PowerPC 64-bit LE requires at least ISA 2.07.  */
+	  const char *default_cpu = (!TARGET_POWERPC64
+				     ? "powerpc"
+				     : (BYTES_BIG_ENDIAN
+					? "powerpc64"
+					: "powerpc64le"));
+
+	  rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (default_cpu);
+	}
+    }
+
   /* If we have a cpu, either through an explicit -mcpu=<xxx> or if the
      compiler was configured with --with-cpu=<xxx>, replace all of the ISA bits
      with those from the cpu, except for options that were explicitly set.  If
@@ -17074,6 +17135,8 @@ spe_init_builtins (void)
 	  continue;
 	}
 
+      /* Cannot define builtin if the instruction is disabled.  */
+      gcc_assert (d->icode != CODE_FOR_nothing);
       switch (insn_data[d->icode].operand[1].mode)
 	{
 	case V2SImode:
@@ -17104,6 +17167,8 @@ spe_init_builtins (void)
 	  continue;
 	}
 
+      /* Cannot define builtin if the instruction is disabled.  */
+      gcc_assert (d->icode != CODE_FOR_nothing);
       switch (insn_data[d->icode].operand[1].mode)
 	{
 	case V2SImode:
@@ -17171,6 +17236,9 @@ paired_init_builtins (void)
 	  continue;
 	}
 
+      /* Cannot define builtin if the instruction is disabled.  */
+      gcc_assert (d->icode != CODE_FOR_nothing);
+
       if (TARGET_DEBUG_BUILTIN)
 	fprintf (stderr, "paired pred #%d, insn = %s [%d], mode = %s\n",
 		 (int)i, get_insn_name (d->icode), (int)d->icode,
@@ -17540,6 +17608,8 @@ altivec_init_builtins (void)
     {
       HOST_WIDE_INT mask = d->mask;
 
+      /* It is expected that these dst built-in functions may have
+	 d->icode equal to CODE_FOR_nothing.  */
       if ((mask & builtin_mask) != mask)
 	{
 	  if (TARGET_DEBUG_BUILTIN)
@@ -17569,7 +17639,11 @@ altivec_init_builtins (void)
       if (rs6000_overloaded_builtin_p (d->code))
 	mode1 = VOIDmode;
       else
-	mode1 = insn_data[d->icode].operand[1].mode;
+	{
+	  /* Cannot define builtin if the instruction is disabled.  */
+	  gcc_assert (d->icode != CODE_FOR_nothing);
+	  mode1 = insn_data[d->icode].operand[1].mode;
+	}
 
       switch (mode1)
 	{
@@ -17617,6 +17691,8 @@ altivec_init_builtins (void)
 	  continue;
 	}
 
+      /* Cannot define builtin if the instruction is disabled.  */
+      gcc_assert (d->icode != CODE_FOR_nothing);
       mode0 = insn_data[d->icode].operand[0].mode;
 
       switch (mode0)
@@ -17804,6 +17880,9 @@ htm_init_builtins (void)
       tree rettype;
       tree argtype;
 
+      /* It is expected that these htm built-in functions may have
+	 d->icode equal to CODE_FOR_nothing.  */
+
       if (TARGET_32BIT && TARGET_POWERPC64)
 	gpr_type_node = long_long_unsigned_type_node;
       else



More information about the Gcc-patches mailing list