https://gcc.gnu.org/g:9a16e2464bb6f6ac637119a9dbaf9648d072e057

commit 9a16e2464bb6f6ac637119a9dbaf9648d072e057
Author: Michael Meissner <meiss...@linux.ibm.com>
Date:   Thu Jul 25 17:34:18 2024 -0400

    Do not allow -mvsx to boost processor to power7.
    
    2024-07-25  Michael Meissner  <meiss...@linux.ibm.com>
    
    gcc/
    
            * config/rs6000/rs6000.cc (report_architecture_mismatch): New 
function.
            Report an error if the user used an option such as -mvsx when the
            default processor would not allow the option.
            (rs6000_option_override_internal): Move some ISA checking code into
            report_architecture_mismatch.
    
    gcc/testsuite/
    
            * gcc.target/powerpc/ppc-target-4.c: Rewrite the test to add 
cpu=power7
            when we need to add VSX support.  Add test for adding cpu=power7 
no-vsx
            to generate only Altivec instructions.
            * gcc.target/powerpc/pr115688.c: Add cpu=power7 when requestion VSX
            instructions.

Diff:
---
 gcc/config/rs6000/rs6000.cc                     | 128 +++++++++++++++---------
 gcc/testsuite/gcc.target/powerpc/ppc-target-4.c |  40 ++++++--
 gcc/testsuite/gcc.target/powerpc/pr115688.c     |   3 +-
 3 files changed, 111 insertions(+), 60 deletions(-)

diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 17f98607905f..6f9f3cce5582 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -1172,6 +1172,7 @@ const int INSN_NOT_AVAILABLE = -1;
 static void rs6000_print_isa_options (FILE *, int, const char *,
                                      HOST_WIDE_INT, HOST_WIDE_INT);
 static HOST_WIDE_INT rs6000_disable_incompatible_switches (void);
+static void report_architecture_mismatch (void);
 
 static enum rs6000_reg_type register_to_reg_type (rtx, bool *);
 static bool rs6000_secondary_reload_move (enum rs6000_reg_type,
@@ -3673,7 +3674,6 @@ rs6000_option_override_internal (bool global_init_p)
   bool ret = true;
 
   HOST_WIDE_INT set_masks;
-  HOST_WIDE_INT ignore_masks;
   int cpu_index = -1;
   int tune_index;
   struct cl_target_option *main_target_opt
@@ -3937,54 +3937,8 @@ rs6000_option_override_internal (bool global_init_p)
     dwarf_offset_size = POINTER_SIZE_UNITS;
 #endif
 
-  /* Handle explicit -mno-{altivec,vsx} and turn off all of
-     the options that depend on those flags.  */
-  ignore_masks = rs6000_disable_incompatible_switches ();
-
-  /* For the newer switches (vsx, dfp, etc.) set some of the older options,
-     unless the user explicitly used the -mno-<option> to disable the code.  */
-  if (TARGET_P9_VECTOR || TARGET_MODULO || TARGET_P9_MISC)
-    rs6000_isa_flags |= (ISA_3_0_MASKS_SERVER & ~ignore_masks);
-  else if (TARGET_P9_MINMAX)
-    {
-      if (cpu_index >= 0)
-       {
-         if (cpu_index == PROCESSOR_POWER9)
-           {
-             /* legacy behavior: allow -mcpu=power9 with certain
-                capabilities explicitly disabled.  */
-             rs6000_isa_flags |= (ISA_3_0_MASKS_SERVER & ~ignore_masks);
-           }
-         else
-           error ("power9 target option is incompatible with %<%s=<xxx>%> "
-                  "for <xxx> less than power9", "-mcpu");
-       }
-      else if ((ISA_3_0_MASKS_SERVER & rs6000_isa_flags_explicit)
-              != (ISA_3_0_MASKS_SERVER & rs6000_isa_flags
-                  & rs6000_isa_flags_explicit))
-       /* Enforce that none of the ISA_3_0_MASKS_SERVER flags
-          were explicitly cleared.  */
-       error ("%qs incompatible with explicitly disabled options",
-              "-mpower9-minmax");
-      else
-       rs6000_isa_flags |= ISA_3_0_MASKS_SERVER;
-    }
-  else if (TARGET_P8_VECTOR || TARGET_POWER8 || TARGET_CRYPTO)
-    rs6000_isa_flags |= (ISA_2_7_MASKS_SERVER & ~ignore_masks);
-  else if (TARGET_VSX)
-    rs6000_isa_flags |= (ISA_2_6_MASKS_SERVER & ~ignore_masks);
-  else if (TARGET_POPCNTD)
-    rs6000_isa_flags |= (ISA_2_6_MASKS_EMBEDDED & ~ignore_masks);
-  else if (TARGET_DFP)
-    rs6000_isa_flags |= (ISA_2_5_MASKS_SERVER & ~ignore_masks);
-  else if (TARGET_CMPB)
-    rs6000_isa_flags |= (ISA_2_5_MASKS_EMBEDDED & ~ignore_masks);
-  else if (TARGET_FPRND)
-    rs6000_isa_flags |= (ISA_2_4_MASKS & ~ignore_masks);
-  else if (TARGET_POPCNTB)
-    rs6000_isa_flags |= (ISA_2_2_MASKS & ~ignore_masks);
-  else if (TARGET_ALTIVEC)
-    rs6000_isa_flags |= (OPTION_MASK_PPC_GFXOPT & ~ignore_masks);
+  /* Report trying to use things like -mmodulo to imply -mcpu=power9.  */
+  report_architecture_mismatch ();
 
   /* Disable VSX and Altivec silently if the user switched cpus to power7 in a
      target attribute or pragma which automatically enables both options,
@@ -25373,6 +25327,82 @@ rs6000_disable_incompatible_switches (void)
   return ignore_masks;
 }
 
+/* In the past, we would boost up the ISA if you selected an -m<foo> option but
+   did not specify the correct -mcpu=<bar> option.  I.e. if you added -mvsx,
+   GCC implictly would assume that you were building for at least power7.  Now,
+   don't allow the -m<foo> option to boost up the ISA level.  But you can still
+   do -mcpu=power7 -mno-vsx or -mcpu=power5 -mno-vsx.  */
+
+static void
+report_architecture_mismatch (void)
+{
+  HOST_WIDE_INT ignore_masks = rs6000_disable_incompatible_switches ();
+
+  static const struct {
+    const HOST_WIDE_INT isa_flags;             /* -m<foo> optiona.  */
+    const HOST_WIDE_INT arch_flags;            /* -mcpu=<proc> level.  */
+    const char *const arch_name;               /* architecture needed.  */
+  } mismatches[] = {
+    {
+      OPTION_MASK_P9_VECTOR | OPTION_MASK_P9_MISC | OPTION_MASK_P9_MINMAX
+      | OPTION_MASK_MODULO,
+      ARCH_MASK_POWER9,
+      "cpu=power9"
+    },
+
+    {
+      OPTION_MASK_P8_VECTOR | OPTION_MASK_CRYPTO,
+      ARCH_MASK_POWER8,
+      "cpu=power8"
+    },
+
+    {
+      OPTION_MASK_VSX | OPTION_MASK_POPCNTD,
+      ARCH_MASK_POWER7,
+      "cpu=power7" },
+
+    {
+      OPTION_MASK_DFP | OPTION_MASK_CMPB,
+      ARCH_MASK_POWER6,
+      "cpu=power6"
+    },
+  };
+
+  HOST_WIDE_INT isa_flags  = rs6000_isa_flags;
+  HOST_WIDE_INT arch_flags = rs6000_arch_flags;
+
+  for (size_t i = 0; i < ARRAY_SIZE (mismatches); i++)
+    {
+      HOST_WIDE_INT mismatch_isa_flags  = mismatches[i].isa_flags  & isa_flags;
+      HOST_WIDE_INT mismatch_arch_flags = mismatches[i].arch_flags & 
arch_flags;
+
+      if (mismatch_isa_flags != 0 && mismatch_arch_flags == 0)
+       {
+         for (size_t j = 0; j < ARRAY_SIZE (rs6000_opt_masks); j++)
+           {
+             HOST_WIDE_INT mask = rs6000_opt_masks[j].mask;
+
+             if ((mask & mismatch_isa_flags) != 0
+                 && (mask & rs6000_isa_flags_explicit) != 0)
+               error ("%qs needs at least %qs",
+                      rs6000_opt_masks[j].name,
+                      mismatches[i].arch_name);
+           }
+
+         rs6000_isa_flags &= ~mismatch_isa_flags;
+       }
+    }
+
+  /* The following old options are used in multiple processors, so silently
+     enable the appropriate ISA options as previous GCC revisions did.  */
+  if (TARGET_FPRND)
+    rs6000_isa_flags |= (ISA_2_4_MASKS & ~ignore_masks);
+  else if (TARGET_POPCNTB)
+    rs6000_isa_flags |= (ISA_2_2_MASKS & ~ignore_masks);
+  else if (TARGET_ALTIVEC)
+    rs6000_isa_flags |= (OPTION_MASK_PPC_GFXOPT & ~ignore_masks);
+}
+
 
 /* Helper function for printing the function name when debugging.  */
 
diff --git a/gcc/testsuite/gcc.target/powerpc/ppc-target-4.c 
b/gcc/testsuite/gcc.target/powerpc/ppc-target-4.c
index 43a98b353cf7..42f5aa354d0a 100644
--- a/gcc/testsuite/gcc.target/powerpc/ppc-target-4.c
+++ b/gcc/testsuite/gcc.target/powerpc/ppc-target-4.c
@@ -1,8 +1,8 @@
 /* { dg-do compile { target { powerpc*-*-* } } } */
 /* { dg-skip-if "" { powerpc*-*-darwin* } } */
 /* { dg-require-effective-target powerpc_vsx_ok } */
-/* { dg-options "-O2 -ffast-math -mdejagnu-cpu=power5 -mno-altivec 
-mabi=altivec -fno-unroll-loops" } */
-/* { dg-final { scan-assembler-times "vaddfp" 1 } } */
+/* { dg-options "-O3 -ffast-math -mdejagnu-cpu=power5 -mno-altivec 
-mabi=altivec -fno-unroll-loops" } */
+/* { dg-final { scan-assembler-times "vaddfp" 2 } } */
 /* { dg-final { scan-assembler-times "xvaddsp" 1 } } */
 /* { dg-final { scan-assembler-times "fadds" 1 } } */
 
@@ -18,10 +18,6 @@
 #error "__VSX__ should not be defined."
 #endif
 
-#pragma GCC target("vsx")
-#include <altivec.h>
-#pragma GCC reset_options
-
 #pragma GCC push_options
 #pragma GCC target("altivec,no-vsx")
 
@@ -33,6 +29,7 @@
 #error "__VSX__ should not be defined."
 #endif
 
+/* Altivec build, generate vaddfp.  */
 void
 av_add (vector float *a, vector float *b, vector float *c)
 {
@@ -40,10 +37,11 @@ av_add (vector float *a, vector float *b, vector float *c)
   unsigned long n = SIZE / 4;
 
   for (i = 0; i < n; i++)
-    a[i] = vec_add (b[i], c[i]);
+    a[i] = b[i] + c[i];
 }
 
-#pragma GCC target("vsx")
+/* cpu=power7 must be used to enable VSX.  */
+#pragma GCC target("cpu=power7,vsx")
 
 #ifndef __ALTIVEC__
 #error "__ALTIVEC__ should be defined."
@@ -53,6 +51,7 @@ av_add (vector float *a, vector float *b, vector float *c)
 #error "__VSX__ should be defined."
 #endif
 
+/* VSX build on power7, generate xsaddsp.  */
 void
 vsx_add (vector float *a, vector float *b, vector float *c)
 {
@@ -60,11 +59,31 @@ vsx_add (vector float *a, vector float *b, vector float *c)
   unsigned long n = SIZE / 4;
 
   for (i = 0; i < n; i++)
-    a[i] = vec_add (b[i], c[i]);
+    a[i] = b[i] + c[i];
+}
+
+#pragma GCC target("cpu=power7,no-vsx")
+
+#ifndef __ALTIVEC__
+#error "__ALTIVEC__ should be defined."
+#endif
+
+#ifdef __VSX__
+#error "__VSX__ should not be defined."
+#endif
+
+/* Altivec build on power7 with no VSX, generate vaddfp.  */
+void
+av2_add (vector float *a, vector float *b, vector float *c)
+{
+  unsigned long i;
+  unsigned long n = SIZE / 4;
+
+  for (i = 0; i < n; i++)
+    a[i] = b[i] + c[i];
 }
 
 #pragma GCC pop_options
-#pragma GCC target("no-vsx,no-altivec")
 
 #ifdef __ALTIVEC__
 #error "__ALTIVEC__ should not be defined."
@@ -74,6 +93,7 @@ vsx_add (vector float *a, vector float *b, vector float *c)
 #error "__VSX__ should not be defined."
 #endif
 
+/* Default power5 build, generate scalar fadds.  */
 void
 norm_add (float *a, float *b, float *c)
 {
diff --git a/gcc/testsuite/gcc.target/powerpc/pr115688.c 
b/gcc/testsuite/gcc.target/powerpc/pr115688.c
index 5222e66ef170..00c7c301436a 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr115688.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr115688.c
@@ -7,7 +7,8 @@
 
 /* Verify there is no ICE under 32 bit env.  */
 
-__attribute__((target("vsx")))
+/* cpu=power7 must be used to enable VSX.  */
+__attribute__((target("cpu=power7,vsx")))
 int test (void)
 {
   return 0;

Reply via email to