When -march=native is passed to host_detect_local_cpu to the backend,
it overrides all command lines after it.  That means

$ gcc -march=native -march=skylake-avx512

is the treated as

$ gcc -march=skylake-avx512 -march=native

Prune joined switches with negation to allow -march=skylake-avx512 to
override previous -march=native on command-line.

        PR driver/69471
        * opts-common.c (prune_options): Also prune joined switches
        with negation.
        * config/i386/i386.opt (march=): Add Negative(march=).
        (mtune=): Add Negative(mtune=).
---
 gcc/config/i386/i386.opt | 4 ++--
 gcc/opts-common.c        | 7 ++++---
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index 9b93241f790..b7998ee7363 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -253,7 +253,7 @@ EnumValue
 Enum(ix86_align_data) String(cacheline) Value(ix86_align_data_type_cacheline)
 
 march=
-Target RejectNegative Joined Var(ix86_arch_string)
+Target RejectNegative Negative(march=) Joined Var(ix86_arch_string)
 Generate code for given CPU.
 
 masm=
@@ -510,7 +510,7 @@ Target Report Mask(TLS_DIRECT_SEG_REFS)
 Use direct references against %gs when accessing tls data.
 
 mtune=
-Target RejectNegative Joined Var(ix86_tune_string)
+Target RejectNegative Negative(mtune=) Joined Var(ix86_tune_string)
 Schedule code for given CPU.
 
 mtune-ctrl=
diff --git a/gcc/opts-common.c b/gcc/opts-common.c
index ee8898b22ec..ba9eb144078 100644
--- a/gcc/opts-common.c
+++ b/gcc/opts-common.c
@@ -1014,8 +1014,8 @@ prune_options (struct cl_decoded_option **decoded_options,
          if (option->neg_index < 0)
            goto keep;
 
-         /* Skip joined switches.  */
-         if ((option->flags & CL_JOINED))
+         /* Skip joined switches if there is no negation.  */
+         if ((option->flags & CL_JOINED) && option->neg_index < 0)
            goto keep;
 
          for (j = i + 1; j < old_decoded_options_count; j++)
@@ -1027,7 +1027,8 @@ prune_options (struct cl_decoded_option **decoded_options,
                continue;
              if (cl_options[next_opt_idx].neg_index < 0)
                continue;
-             if ((cl_options[next_opt_idx].flags & CL_JOINED))
+             if ((cl_options[next_opt_idx].flags & CL_JOINED)
+                 && cl_options[next_opt_idx].neg_index < 0)
                  continue;
              if (cancel_option (opt_idx, next_opt_idx, next_opt_idx))
                break;
-- 
2.20.1

Reply via email to