Hi!

On Mon, Sep 05, 2016 at 09:00:30PM +0200, Uros Bizjak wrote:
> OK as far as x86 target is concerned, but please allow a day for David
> to eventually comment on the implementation.

And here is the updated i386 patch, on top of the generic patch I've just
posted.  Compared to the last patch, this one now includes diagnostics,
uses the new opts-common.c helper and also stops using the perhaps fancy,
but absolutely l10n incompatible technique with prefix/suffix/sw variables
in various diagnostics - the words switch and attribute couldn't be
translated and would appear somewhere in a translated sequence.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2016-09-05  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/77475
        * config/i386/i386.c (ix86_parse_stringop_strategy_string): Simplify,
        use %qs instead of %s where desirable, use argument instead of arg in
        the diagnostic wording, add list of supported strategies and
        spellcheck hint.
        (ix86_option_override_internal): Emit target("m...") instead of
        option("m...") in the diagnostic.  Use %qs instead of %s in invalid
        -march/-mtune option diagnostic.  Add list of supported arches/tunings
        and spellcheck hint.  Remove prefix, suffix and sw variables, use
        main_args_p ? "..." : "..." in diagnostics to make translation
        possible.

        * gcc.target/i386/pr65990.c: Adjust expected diagnostics.
        * gcc.dg/march-generic.c: Likewise.
        * gcc.target/i386/spellcheck-options-1.c: New test.
        * gcc.target/i386/spellcheck-options-2.c: New test.
        * gcc.target/i386/spellcheck-options-3.c: New test.
        * gcc.target/i386/spellcheck-options-4.c: New test.

--- gcc/config/i386/i386.c.jj   2016-09-06 16:55:35.524605779 +0200
+++ gcc/config/i386/i386.c      2016-09-06 19:45:03.126299652 +0200
@@ -4516,6 +4517,7 @@ ix86_parse_stringop_strategy_string (cha
   const struct stringop_algs *default_algs;
   stringop_size_range input_ranges[MAX_STRINGOP_ALGS];
   char *curr_range_str, *next_range_str;
+  const char *opt = is_memset ? "-mmemset_strategy=" : "-mmemcpy_strategy=";
   int i = 0, n = 0;
 
   if (is_memset)
@@ -4537,15 +4539,13 @@ ix86_parse_stringop_strategy_string (cha
       if (3 != sscanf (curr_range_str, "%20[^:]:%d:%10s",
                        alg_name, &maxs, align))
         {
-          error ("wrong arg %s to option %s", curr_range_str,
-                 is_memset ? "-mmemset_strategy=" : "-mmemcpy_strategy=");
+         error ("wrong argument %qs to option %qs", curr_range_str, opt);
           return;
         }
 
       if (n > 0 && (maxs < (input_ranges[n - 1].max + 1) && maxs != -1))
         {
-          error ("size ranges of option %s should be increasing",
-                 is_memset ? "-mmemset_strategy=" : "-mmemcpy_strategy=");
+         error ("size ranges of option %qs should be increasing", opt);
           return;
         }
 
@@ -4555,9 +4555,25 @@ ix86_parse_stringop_strategy_string (cha
 
       if (i == last_alg)
         {
-          error ("wrong stringop strategy name %s specified for option %s",
-                 alg_name,
-                 is_memset ? "-mmemset_strategy=" : "-mmemcpy_strategy=");
+         error ("wrong strategy name %qs specified for option %qs",
+                alg_name, opt);
+
+         auto_vec <const char *> candidates;
+         for (i = 0; i < last_alg; i++)
+           if ((stringop_alg) i != rep_prefix_8_byte || TARGET_64BIT)
+             candidates.safe_push (stringop_alg_names[i]);
+
+         char *s;
+         const char *hint
+           = candidates_list_and_hint (alg_name, s, candidates);
+         if (hint)
+           inform (input_location,
+                   "valid arguments to %qs are: %s; did you mean %qs?",
+                   opt, s, hint);
+         else
+           inform (input_location, "valid arguments to %qs are: %s",
+                   opt, s);
+         XDELETEVEC (s);
           return;
         }
 
@@ -4565,10 +4581,8 @@ ix86_parse_stringop_strategy_string (cha
          && !TARGET_64BIT)
        {
          /* rep; movq isn't available in 32-bit code.  */
-         error ("stringop strategy name %s specified for option %s "
-                "not supported for 32-bit code",
-                 alg_name,
-                 is_memset ? "-mmemset_strategy=" : "-mmemcpy_strategy=");
+         error ("strategy name %qs specified for option %qs "
+                "not supported for 32-bit code", alg_name, opt);
          return;
        }
 
@@ -4580,8 +4594,7 @@ ix86_parse_stringop_strategy_string (cha
         input_ranges[n].noalign = true;
       else
         {
-          error ("unknown alignment %s specified for option %s",
-                 align, is_memset ? "-mmemset_strategy=" : 
"-mmemcpy_strategy=");
+         error ("unknown alignment %qs specified for option %qs", align, opt);
           return;
         }
       n++;
@@ -4592,15 +4605,13 @@ ix86_parse_stringop_strategy_string (cha
   if (input_ranges[n - 1].max != -1)
     {
       error ("the max value for the last size range should be -1"
-             " for option %s",
-             is_memset ? "-mmemset_strategy=" : "-mmemcpy_strategy=");
+             " for option %qs", opt);
       return;
     }
 
   if (n > MAX_STRINGOP_ALGS)
     {
-      error ("too many size ranges specified in option %s",
-             is_memset ? "-mmemset_strategy=" : "-mmemcpy_strategy=");
+      error ("too many size ranges specified in option %qs", opt);
       return;
     }
 
@@ -4731,9 +4742,6 @@ ix86_option_override_internal (bool main
   int i;
   unsigned int ix86_arch_mask;
   const bool ix86_tune_specified = (opts->x_ix86_tune_string != NULL);
-  const char *prefix;
-  const char *suffix;
-  const char *sw;
 
 #define PTA_3DNOW              (HOST_WIDE_INT_1 << 0)
 #define PTA_3DNOW_A            (HOST_WIDE_INT_1 << 1)
@@ -5031,21 +5039,6 @@ ix86_option_override_internal (bool main
 
   int const pta_size = ARRAY_SIZE (processor_alias_table);
 
-  /* Set up prefix/suffix so the error messages refer to either the command
-     line argument, or the attribute(target).  */
-  if (main_args_p)
-    {
-      prefix = "-m";
-      suffix = "";
-      sw = "switch";
-    }
-  else
-    {
-      prefix = "option(\"";
-      suffix = "\")";
-      sw = "attribute";
-    }
-
   /* Turn off both OPTION_MASK_ABI_64 and OPTION_MASK_ABI_X32 if
      TARGET_64BIT_DEFAULT is true and TARGET_64BIT is false.  */
   if (TARGET_64BIT_DEFAULT && !TARGET_64BIT_P (opts->x_ix86_isa_flags))
@@ -5118,9 +5111,13 @@ ix86_option_override_internal (bool main
          opts->x_ix86_tune_string = "generic";
        }
       else if (!strcmp (opts->x_ix86_tune_string, "x86-64"))
-        warning (OPT_Wdeprecated, "%stune=x86-64%s is deprecated; use "
-                 "%stune=k8%s or %stune=generic%s instead as appropriate",
-                 prefix, suffix, prefix, suffix, prefix, suffix);
+        warning (OPT_Wdeprecated,
+                main_args_p
+                ? "%<-mtune=x86-64%> is deprecated; use %<-mtune=k8%> "
+                  "or %<-mtune=generic%> instead as appropriate"
+                : "%<target(\"tune=x86-64\")%> is deprecated; use "
+                  "%<target(\"tune=k8\")%> or %<target(\"tune=generic\")%> "
+                  "instead as appropriate");
     }
   else
     {
@@ -5474,14 +5471,48 @@ ix86_option_override_internal (bool main
     error ("Intel MPX does not support x32");
 
   if (!strcmp (opts->x_ix86_arch_string, "generic"))
-    error ("generic CPU can be used only for %stune=%s %s",
-          prefix, suffix, sw);
+    error (main_args_p
+          ? "%<generic%> CPU can be used only for %<-mtune=%> switch"
+          : "%<generic%> CPU can be used only for "
+            "%<target(\"tune=\")%> attribute");
   else if (!strcmp (opts->x_ix86_arch_string, "intel"))
-    error ("intel CPU can be used only for %stune=%s %s",
-          prefix, suffix, sw);
+    error (main_args_p
+          ? "%<intel%> CPU can be used only for %<-mtune=%> switch"
+          : "%<intel%> CPU can be used only for "
+            "%<target(\"tune=\")%> attribute");
   else if (i == pta_size)
-    error ("bad value (%s) for %sarch=%s %s",
-          opts->x_ix86_arch_string, prefix, suffix, sw);
+    {
+      error (main_args_p
+            ? "bad value (%qs) for %<-march=%> switch"
+            : "bad value (%qs) for %<target(\"arch=\")%> attribute",
+            opts->x_ix86_arch_string);
+
+      auto_vec <const char *> candidates;
+      for (i = 0; i < pta_size; i++)
+       if (strcmp (processor_alias_table[i].name, "generic")
+           && strcmp (processor_alias_table[i].name, "intel")
+           && (!TARGET_64BIT_P (opts->x_ix86_isa_flags)
+               || (processor_alias_table[i].flags & PTA_64BIT)))
+         candidates.safe_push (processor_alias_table[i].name);
+
+      char *s;
+      const char *hint
+       = candidates_list_and_hint (opts->x_ix86_arch_string, s, candidates);
+      if (hint)
+       inform (input_location,
+               main_args_p
+               ? "valid arguments to %<-march=%> switch are: "
+                 "%s; did you mean %qs?"
+               : "valid arguments to %<target(\"arch=\")%> attribute are: "
+                 "%s; did you mean %qs?", s, hint);
+      else
+       inform (input_location,
+               main_args_p
+               ? "valid arguments to %<-march=%> switch are: %s"
+               : "valid arguments to %<target(\"arch=\")%> attribute are: %s",
+               s);
+      XDELETEVEC (s);
+    }
 
   ix86_arch_mask = 1u << ix86_arch;
   for (i = 0; i < X86_ARCH_LAST; ++i)
@@ -5523,8 +5554,36 @@ ix86_option_override_internal (bool main
       }
 
   if (ix86_tune_specified && i == pta_size)
-    error ("bad value (%s) for %stune=%s %s",
-          opts->x_ix86_tune_string, prefix, suffix, sw);
+    {
+      error (main_args_p
+            ? "bad value (%qs) for %<-mtune=%> switch"
+            : "bad value (%qs) for %<target(\"tune=\")%> attribute",
+            opts->x_ix86_tune_string);
+
+      auto_vec <const char *> candidates;
+      for (i = 0; i < pta_size; i++)
+       if (!TARGET_64BIT_P (opts->x_ix86_isa_flags)
+           || (processor_alias_table[i].flags & PTA_64BIT))
+         candidates.safe_push (processor_alias_table[i].name);
+
+      char *s;
+      const char *hint
+       = candidates_list_and_hint (opts->x_ix86_tune_string, s, candidates);
+      if (hint)
+       inform (input_location,
+               main_args_p
+               ? "valid arguments to %<-mtune=%> switch are: "
+                 "%s; did you mean %qs?"
+               : "valid arguments to %<target(\"tune=\")%> attribute are: "
+                 "%s; did you mean %qs?", s, hint);
+      else
+       inform (input_location,
+               main_args_p
+               ? "valid arguments to %<-mtune=%> switch are: %s"
+               : "valid arguments to %<target(\"tune=\")%> attribute are: %s",
+               s);
+      XDELETEVEC (s);
+    }
 
   set_ix86_tune_features (ix86_tune, opts->x_ix86_dump_tunes);
 
@@ -5623,7 +5682,9 @@ ix86_option_override_internal (bool main
             & ~opts->x_ix86_isa_flags_explicit);
 
       if (TARGET_RTD_P (opts->x_target_flags))
-       warning (0, "%srtd%s is ignored in 64bit mode", prefix, suffix);
+       warning (0,
+                main_args_p ? "%<-mrtd%> is ignored in 64bit mode"
+                            : "%<target(\"rtd\")%> is ignored in 64bit mode");
     }
   else
     {
@@ -5744,7 +5805,9 @@ ix86_option_override_internal (bool main
   /* Accept -msseregparm only if at least SSE support is enabled.  */
   if (TARGET_SSEREGPARM_P (opts->x_target_flags)
       && ! TARGET_SSE_P (opts->x_ix86_isa_flags))
-    error ("%ssseregparm%s used without SSE enabled", prefix, suffix);
+    error (main_args_p
+          ? "%<-msseregparm%> used without SSE enabled"
+          : "%<target(\"sseregparm\")%> used without SSE enabled");
 
   if (opts_set->x_ix86_fpmath)
     {
@@ -5809,8 +5872,12 @@ ix86_option_override_internal (bool main
       && !(opts->x_target_flags & MASK_ACCUMULATE_OUTGOING_ARGS))
     {
       if (opts_set->x_target_flags & MASK_ACCUMULATE_OUTGOING_ARGS)
-       warning (0, "stack probing requires %saccumulate-outgoing-args%s "
-                "for correctness", prefix, suffix);
+       warning (0,
+                main_args_p
+                ? "stack probing requires %<-maccumulate-outgoing-args%> "
+                  "for correctness"
+                : "stack probing requires "
+                  "%<target(\"accumulate-outgoing-args\")%> for correctness");
       opts->x_target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS;
     }
 
@@ -5820,8 +5887,11 @@ ix86_option_override_internal (bool main
       && !(opts->x_target_flags & MASK_ACCUMULATE_OUTGOING_ARGS))
     {
       if (opts_set->x_target_flags & MASK_ACCUMULATE_OUTGOING_ARGS)
-       warning (0, "fixed ebp register requires %saccumulate-outgoing-args%s",
-                prefix, suffix);
+       warning (0,
+                main_args_p
+                ? "fixed ebp register requires %<-maccumulate-outgoing-args%>"
+                : "fixed ebp register requires "
+                  "%<target(\"accumulate-outgoing-args\")%>");
       opts->x_target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS;
     }
 
--- gcc/testsuite/gcc.target/i386/pr65990.c.jj  2016-09-05 19:27:03.016674736 
+0200
+++ gcc/testsuite/gcc.target/i386/pr65990.c     2016-09-06 17:47:11.812776172 
+0200
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options "-mtune=btver2 -mmemcpy-strategy=rep_8byte:-1:noalign" }
 
-/* { dg-error "stringop strategy name rep_8byte specified for option 
-mmemcpy_strategy= not supported for 32-bit code" "" { target ia32 } 0 } */
+/* { dg-error "stringop strategy name 'rep_8byte' specified for option 
'-mmemcpy_strategy=' not supported for 32-bit code" "" { target ia32 } 0 } */
 
 struct U9
 {
--- gcc/testsuite/gcc.dg/march-generic.c.jj     2014-11-11 00:06:08.000000000 
+0100
+++ gcc/testsuite/gcc.dg/march-generic.c        2016-09-06 22:19:32.278111025 
+0200
@@ -1,6 +1,6 @@
 /* { dg-do compile { target i?86-*-* x86_64-*-* } } */
 /* { dg-skip-if "" { *-*-* } { "-march=*" } { "" } } */
 /* { dg-options "-march=generic" } */
-/* { dg-error "generic CPU can be used only for -mtune" "" { target *-*-* } 0 
} */
+/* { dg-error "'generic' CPU can be used only for '-mtune=' switch" "" { 
target *-*-* } 0 } */
 /* { dg-bogus "march" "" { target *-*-* } 0 } */
 int i;
--- gcc/testsuite/gcc.target/i386/spellcheck-options-1.c.jj     2016-09-06 
19:33:10.134236964 +0200
+++ gcc/testsuite/gcc.target/i386/spellcheck-options-1.c        2016-09-06 
19:39:21.623580368 +0200
@@ -0,0 +1,7 @@
+/* Verify that we provide a hint if the user misspells an option argument
+   (PR middle-end/77475).  */
+
+/* { dg-do compile } */
+/* { dg-options "-march=hasvel" } */
+/* { dg-error "bad value .'hasvel'. for '-march=' switch"  "" { target *-*-* } 
0 } */
+/* { dg-message "valid arguments to '-march=' switch are: \[^\n\r]*; did you 
mean 'haswell'?"  "" { target *-*-* } 0 } */
--- gcc/testsuite/gcc.target/i386/spellcheck-options-2.c.jj     2016-09-06 
19:39:39.433357123 +0200
+++ gcc/testsuite/gcc.target/i386/spellcheck-options-2.c        2016-09-06 
19:40:02.367069650 +0200
@@ -0,0 +1,7 @@
+/* Verify that we provide a hint if the user misspells an option argument
+   (PR middle-end/77475).  */
+
+/* { dg-do compile } */
+/* { dg-options "-mtune=hasvel" } */
+/* { dg-error "bad value .'hasvel'. for '-mtune=' switch"  "" { target *-*-* } 
0 } */
+/* { dg-message "valid arguments to '-mtune=' switch are: \[^\n\r]*; did you 
mean 'haswell'?"  "" { target *-*-* } 0 } */
--- gcc/testsuite/gcc.target/i386/spellcheck-options-3.c.jj     2016-09-06 
19:40:13.177934137 +0200
+++ gcc/testsuite/gcc.target/i386/spellcheck-options-3.c        2016-09-06 
19:46:25.200270859 +0200
@@ -0,0 +1,7 @@
+/* Verify that we provide a hint if the user misspells an option argument
+   (PR middle-end/77475).  */
+
+/* { dg-do compile } */
+/* { dg-options "-mmemcpy-strategy=unroled_looop:8:align" } */
+/* { dg-error "wrong strategy name 'unroled_looop' specified for option 
'-mmemcpy_strategy='"  "" { target *-*-* } 0 } */
+/* { dg-message "valid arguments to '-mmemcpy_strategy=' are: \[^\n\r]*; did 
you mean 'unrolled_loop'?"  "" { target *-*-* } 0 } */
--- gcc/testsuite/gcc.target/i386/spellcheck-options-4.c.jj     2016-09-06 
19:46:37.500116681 +0200
+++ gcc/testsuite/gcc.target/i386/spellcheck-options-4.c        2016-09-06 
19:48:04.486026318 +0200
@@ -0,0 +1,7 @@
+/* Verify that we provide a hint if the user misspells an option argument
+   (PR middle-end/77475).  */
+
+/* { dg-do compile } */
+
+__attribute__((target ("arch=hasvel"))) void foo (void) {} /* { dg-error "bad 
value .'hasvel'. for 'target..arch=..' attribute" } */
+/* { dg-message "valid arguments to 'target..arch=..' attribute are: 
\[^\n\r]*; did you mean 'haswell'?"  "" { target *-*-* } 6 } */


        Jakub

Reply via email to