Internal testing recently revealed that use of the -mno-power9-vector
target option in combination with the -mcpu=power9 target option
results in termination of gcc with the error message:

  power9-dform requires power9-vector

This same problem is seen if the -mno-power9-vector target option is
specified to a gcc which was built using --with-cpu=power9 as an
argument to configure.

In both cases, the preferred behavior is that the target option
-mno-power9-vector causes power9-dform to be automatically disabled.
 This patch implements the preferred behavior and adds a test case to
demonstrate the fix.

The patch has been bootstrapped and tested with no regressions on both
powerpc64-unknown-linux-gnu and powerpc64le-unknown-linux-gnu.  Is this
ok for the trunk?

gcc/testsuite/ChangeLog:

2017-03-21  Kelvin Nilsen  <kel...@gcc.gnu.org>

        * gcc.target/powerpc/p9-options-1.c: New test.

gcc/ChangeLog:

2017-03-21  Kelvin Nilsen  <kel...@gcc.gnu.org>

        * config/rs6000/rs6000.c (rs6000_option_override_internal): Change
        handling of certain combinations of target options, including the
        combinations -mpower8-vector vs. -mno-vsx, -mpower8-vector vs.
        -mno-power8-vector, and -mpower9_dform vs. -mno-power9-vector.

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c  (revision 246212)
+++ gcc/config/rs6000/rs6000.c  (working copy)
@@ -4246,9 +4246,22 @@ rs6000_option_override_internal (bool global_init_
 
   if (TARGET_P8_VECTOR && !TARGET_VSX)
     {
-      if (rs6000_isa_flags_explicit & OPTION_MASK_P8_VECTOR)
+      if ((rs6000_isa_flags_explicit & OPTION_MASK_P8_VECTOR)
+         && (rs6000_isa_flags_explicit & OPTION_MASK_VSX))
        error ("-mpower8-vector requires -mvsx");
-      rs6000_isa_flags &= ~OPTION_MASK_P8_VECTOR;
+      else if ((rs6000_isa_flags_explicit & OPTION_MASK_P8_VECTOR) == 0)
+       {
+         rs6000_isa_flags &= ~OPTION_MASK_P8_VECTOR;
+         if (rs6000_isa_flags_explicit & OPTION_MASK_VSX)
+           rs6000_isa_flags_explicit |= OPTION_MASK_P8_VECTOR;
+       }
+      else
+       {
+         /* OPTION_MASK_P8_VECTOR is explicit, and OPTION_MASK_VSX is
+            not explicit.  */
+         rs6000_isa_flags |= OPTION_MASK_VSX;
+         rs6000_isa_flags_explicit |= OPTION_MASK_VSX;
+       }
     }
 
   if (TARGET_VSX_TIMODE && !TARGET_VSX)
@@ -4448,9 +4461,22 @@ rs6000_option_override_internal (bool global_init_
         error messages.  However, if users have managed to select
         power9-vector without selecting power8-vector, they
         already know about undocumented flags.  */
-      if (rs6000_isa_flags_explicit & OPTION_MASK_P8_VECTOR)
+      if ((rs6000_isa_flags_explicit & OPTION_MASK_P9_VECTOR) &&
+         (rs6000_isa_flags_explicit & OPTION_MASK_P8_VECTOR))
        error ("-mpower9-vector requires -mpower8-vector");
-      rs6000_isa_flags &= ~OPTION_MASK_P9_VECTOR;
+      else if ((rs6000_isa_flags_explicit & OPTION_MASK_P9_VECTOR) == 0)
+       {
+         rs6000_isa_flags &= ~OPTION_MASK_P9_VECTOR;
+         if (rs6000_isa_flags_explicit & OPTION_MASK_P8_VECTOR)
+           rs6000_isa_flags_explicit |= OPTION_MASK_P9_VECTOR;
+       }
+      else
+       {
+         /* OPTION_MASK_P9_VECTOR is explicit and
+            OPTION_MASK_P8_VECTOR is not explicit.  */
+         rs6000_isa_flags |= OPTION_MASK_P8_VECTOR;
+         rs6000_isa_flags_explicit |= OPTION_MASK_P8_VECTOR;
+       }
     }
 
   /* -mpower9-dform turns on both -mpower9-dform-scalar and
@@ -4479,10 +4505,25 @@ rs6000_option_override_internal (bool global_init_
         error messages.  However, if users have managed to select
         power9-dform without selecting power9-vector, they
         already know about undocumented flags.  */
-      if (rs6000_isa_flags_explicit & OPTION_MASK_P9_VECTOR)
+      if ((rs6000_isa_flags_explicit & OPTION_MASK_P9_VECTOR)
+         && (rs6000_isa_flags_explicit & (OPTION_MASK_P9_DFORM_SCALAR
+                                          | OPTION_MASK_P9_DFORM_VECTOR)))
        error ("-mpower9-dform requires -mpower9-vector");
-      rs6000_isa_flags &= ~(OPTION_MASK_P9_DFORM_SCALAR
-                           | OPTION_MASK_P9_DFORM_VECTOR);
+      else if (rs6000_isa_flags_explicit & OPTION_MASK_P9_VECTOR)
+       {
+         rs6000_isa_flags &=
+           ~(OPTION_MASK_P9_DFORM_SCALAR | OPTION_MASK_P9_DFORM_VECTOR);
+         rs6000_isa_flags_explicit |=
+           (OPTION_MASK_P9_DFORM_SCALAR | OPTION_MASK_P9_DFORM_VECTOR);
+       }
+      else
+       {
+         /* We know that OPTION_MASK_P9_VECTOR is not explicit and
+            OPTION_MASK_P9_DFORM_SCALAR or OPTION_MASK_P9_DORM_VECTOR
+            may be explicit.  */
+         rs6000_isa_flags |= OPTION_MASK_P9_VECTOR;
+         rs6000_isa_flags_explicit |= OPTION_MASK_P9_VECTOR;
+       }
     }
 
   if (TARGET_P9_DFORM_SCALAR && !TARGET_UPPER_REGS_DF)
Index: gcc/testsuite/gcc.target/powerpc/p9-options-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/p9-options-1.c     (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/p9-options-1.c     (working copy)
@@ -0,0 +1,28 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { 
"-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9 -mno-power9-vector" } */
+
+#include <altivec.h>
+
+/* This program's "test for excess errors" demonstrates that combining
+   the target options -mcpu=power9 and -mno-power9-vector does not
+   result in an error.  A previous version of the compiler aborted
+   with the error message:
+
+      "power9-dform requires power9-vector."
+
+   when these two options were used in combination.
+
+   The newer version of the compiler, instead, automatically disables
+   power9-dform when the -mno-power9-vector command-line option is
+   specified.  */
+int
+test_any_equal (vector bool char *arg1_p, vector bool char *arg2_p)
+{
+  vector bool char arg_1 = *arg1_p;
+  vector bool char arg_2 = *arg2_p;
+
+  return vec_any_eq (arg_1, arg_2);
+}
+

Reply via email to