gcc/ChangeLog:

        * config/aarch64/aarch64-opts.h (enum aarch64_autovec_preference_enum):
        Add AARCH64_AUTOVEC_SPECIFIC_MODE value.
        * config/aarch64/aarch64-protos.h (aarch64_validate_autovec_preference):
        New function.
        * config/aarch64/aarch64.cc (aarch64_autovec_preference):
        New static variable.
        (aarch64_autovec_preference_mode): Likewise.
        (aarch64_override_options_internal): Update
        aarch64_autovec_preference logic
        (aarch64_override_options): Handle aarch64_autovec_preference.
        (aarch64_autovectorize_vector_modes): Add logic for selecting one
        particular mode with aarch64_autovec_preference.
        * config/aarch64/aarch64.opt: Update aarch64_autovec_preference.
        * doc/params.texi: Update documentation.

-- >8 --

I thought about this some more and thought that Kyrylo's suggestion on IRC
was actually easier and better than I initially thought.

I only change --param=aarch64-autovec-preference as this is a pretty
hacky and non-user friendly option. But it is useful for testing
and debugging.

Similar to riscv's --param=riscv-autovec-mode.

Regression tested and bootstrapped on aarch64-linux-gnu and
x86_64-linux-gnu.

Thoughts?
Okay for master?

Thanks,
Alfie
---
 gcc/config/aarch64/aarch64-opts.h   |  3 +-
 gcc/config/aarch64/aarch64-protos.h |  3 ++
 gcc/config/aarch64/aarch64.cc       | 58 +++++++++++++++++++++++++++--
 gcc/config/aarch64/aarch64.opt      | 44 +++++++++++-----------
 gcc/doc/params.texi                 |  8 ++--
 5 files changed, 87 insertions(+), 29 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-opts.h 
b/gcc/config/aarch64/aarch64-opts.h
index 423285d6b0f..2b3870a3c36 100644
--- a/gcc/config/aarch64/aarch64-opts.h
+++ b/gcc/config/aarch64/aarch64-opts.h
@@ -121,7 +121,8 @@ enum aarch64_autovec_preference_enum {
   AARCH64_AUTOVEC_ASIMD_ONLY,
   AARCH64_AUTOVEC_SVE_ONLY,
   AARCH64_AUTOVEC_PREFER_ASIMD,
-  AARCH64_AUTOVEC_PREFER_SVE
+  AARCH64_AUTOVEC_PREFER_SVE,
+  AARCH64_AUTOVEC_SPECIFIC_MODE
 };
 
 /* An enum specifying how to handle load and store pairs using
diff --git a/gcc/config/aarch64/aarch64-protos.h 
b/gcc/config/aarch64/aarch64-protos.h
index e8ae3d42794..22fd1c68b05 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -1257,6 +1257,9 @@ bool aarch64_validate_march (const char *, aarch64_arch *,
 bool aarch64_validate_mcpu (const char *, aarch64_cpu *,
                            aarch64_feature_flags *);
 bool aarch64_validate_mtune (const char *, aarch64_cpu *);
+bool aarch64_validate_autovec_preference (const char *,
+                                         aarch64_autovec_preference_enum *,
+                                         opt_machine_mode *);
 std::string aarch64_get_extension_string_for_isa_flags (aarch64_feature_flags,
                                                        aarch64_feature_flags);
 std::string aarch64_get_arch_string_for_assembler (aarch64_arch,
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index f9d906f449f..d8bd0cc74f1 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -602,6 +602,9 @@ aarch64_lookup_sysreg_map (const char *regname)
 
 /* The current tuning set.  */
 struct tune_params aarch64_tune_params = generic_tunings;
+aarch64_autovec_preference_enum aarch64_autovec_preference
+  = AARCH64_AUTOVEC_DEFAULT;
+machine_mode aarch64_autovec_preference_mode = VOIDmode;
 
 /* If NAME is the name of an arm:: attribute that describes shared state,
    return its associated AARCH64_STATE_* flags, otherwise return 0.  */
@@ -20252,10 +20255,9 @@ aarch64_override_options_internal (struct gcc_options 
*opts,
   /* Synchronize the -mautovec-preference and aarch64_autovec_preference using
      whichever one is not default.  If both are set then prefer the param flag
      over the parameters.  */
-  if (opts->x_autovec_preference != AARCH64_AUTOVEC_DEFAULT)
-    SET_OPTION_IF_UNSET (opts, opts_set,
-                        aarch64_autovec_preference,
-                        opts->x_autovec_preference);
+  if (opts->x_autovec_preference != AARCH64_AUTOVEC_DEFAULT
+      && aarch64_autovec_preference == AARCH64_AUTOVEC_DEFAULT)
+    aarch64_autovec_preference = opts->x_autovec_preference;
 
   aarch64_override_options_after_change_1 (opts);
 }
@@ -20427,6 +20429,30 @@ static const struct aarch_branch_protect_type 
aarch64_branch_protect_types[] =
   { NULL, false, NULL, NULL, 0 }
 };
 
+/* Validate a command-line param autovec preference option.  */
+
+bool
+aarch64_validate_autovec_preference (
+  const char *str,
+  aarch64_autovec_preference_enum *preference,
+  machine_mode *preferred_mode)
+{
+  if (opt_enum_arg_to_value (OPT_mautovec_preference_, str, (int *) preference,
+                            CL_TARGET))
+    return true;
+
+  machine_mode mode;
+  if (parse_machine_mode (str, &mode) && VECTOR_MODE_P (mode))
+    {
+      *preference = AARCH64_AUTOVEC_SPECIFIC_MODE;
+      *preferred_mode = mode;
+      return true;
+    }
+
+  error ("invalid mode for param=aarch64-autovec-preference %<%s%>", str);
+  return false;
+}
+
 /* Implement TARGET_OPTION_OVERRIDE.  This is called once in the beginning
    and is used to parse the -m{cpu,tune,arch} strings and setup the initial
    tuning structs.  In particular it must set selected_tune and
@@ -20465,6 +20491,11 @@ aarch64_override_options (void)
   if (aarch64_tune_string)
     aarch64_validate_mtune (aarch64_tune_string, &tune);
 
+  if (aarch64_autovec_preference_string)
+    aarch64_validate_autovec_preference (aarch64_autovec_preference_string,
+                                        &aarch64_autovec_preference,
+                                        &aarch64_autovec_preference_mode);
+
 #ifdef SUBTARGET_OVERRIDE_OPTIONS
   SUBTARGET_OVERRIDE_OPTIONS;
 #endif
@@ -24083,6 +24114,7 @@ aarch64_autovectorize_vector_modes (vector_modes 
*modes, bool)
        for this case.  */
     V2SImode
   };
+  static bool selected_mode_warning_emitted = false;
 
   /* Try using N-byte SVE modes only after trying N-byte Advanced SIMD mode.
      This is because:
@@ -24117,6 +24149,24 @@ aarch64_autovectorize_vector_modes (vector_modes 
*modes, bool)
   while (sve_i < ARRAY_SIZE (sve_modes))
    modes->safe_push (sve_modes[sve_i++]);
 
+  if (aarch64_autovec_preference == AARCH64_AUTOVEC_SPECIFIC_MODE)
+    {
+      if (modes->contains (aarch64_autovec_preference_mode))
+       {
+         modes->truncate (0);
+         modes->safe_push (aarch64_autovec_preference_mode);
+         return 0;
+       }
+      else if (!selected_mode_warning_emitted)
+       {
+         selected_mode_warning_emitted = true;
+         warning (0,
+                  "selected mode %<%s%> not an available vector mode, "
+                  "using default cost model behaviour",
+                  aarch64_autovec_preference_string);
+       }
+    }
+
   unsigned int flags = 0;
   if (aarch64_vect_compare_costs)
     flags |= VECT_COMPARE_COSTS;
diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt
index deccc6c8887..63342c83070 100644
--- a/gcc/config/aarch64/aarch64.opt
+++ b/gcc/config/aarch64/aarch64.opt
@@ -315,6 +315,24 @@ Force an ISA selection strategy for auto-vectorization.  
For best performance it
 is highly recommended to use -mcpu or -mtune instead.  This parameter should
 only be used for code exploration.
 
+Enum
+Name(aarch64_autovec_preference) Type(enum aarch64_autovec_preference_enum) 
UnknownError(unknown autovec preference %qs)
+
+EnumValue
+Enum(aarch64_autovec_preference) String(default) Value(AARCH64_AUTOVEC_DEFAULT)
+
+EnumValue
+Enum(aarch64_autovec_preference) String(asimd-only) 
Value(AARCH64_AUTOVEC_ASIMD_ONLY)
+
+EnumValue
+Enum(aarch64_autovec_preference) String(sve-only) 
Value(AARCH64_AUTOVEC_SVE_ONLY)
+
+EnumValue
+Enum(aarch64_autovec_preference) String(prefer-asimd) 
Value(AARCH64_AUTOVEC_PREFER_ASIMD)
+
+EnumValue
+Enum(aarch64_autovec_preference) String(prefer-sve) 
Value(AARCH64_AUTOVEC_PREFER_SVE)
+
 mmax-vectorization
 Target Var(flag_aarch64_max_vectorization) Save
 Override the scalar cost model such that vectorization is always profitable.
@@ -384,27 +402,11 @@ Target Joined UInteger Var(aarch64_double_recp_precision) 
Init(2) IntegerRange(1
 The number of Newton iterations for calculating the reciprocal for double 
type.  The precision of division is proportional to this param when division 
approximation is enabled.  The default value is 2.
 
 -param=aarch64-autovec-preference=
-Target Joined Var(aarch64_autovec_preference) Enum(aarch64_autovec_preference) 
Init(AARCH64_AUTOVEC_DEFAULT) Param
-An old alias for -mautovec-preference.  If both -mautovec-preference and
---param=aarch64-autovec-preference are passed, the --param value will be used.
-
-Enum
-Name(aarch64_autovec_preference) Type(enum aarch64_autovec_preference_enum) 
UnknownError(unknown autovec preference %qs)
-
-EnumValue
-Enum(aarch64_autovec_preference) String(default) Value(AARCH64_AUTOVEC_DEFAULT)
-
-EnumValue
-Enum(aarch64_autovec_preference) String(asimd-only) 
Value(AARCH64_AUTOVEC_ASIMD_ONLY)
-
-EnumValue
-Enum(aarch64_autovec_preference) String(sve-only) 
Value(AARCH64_AUTOVEC_SVE_ONLY)
-
-EnumValue
-Enum(aarch64_autovec_preference) String(prefer-asimd) 
Value(AARCH64_AUTOVEC_PREFER_ASIMD)
-
-EnumValue
-Enum(aarch64_autovec_preference) String(prefer-sve) 
Value(AARCH64_AUTOVEC_PREFER_SVE)
+Target RejectNegative Joined Var(aarch64_autovec_preference_string) Param
+Force an ISA selection strategy for auto-vectorization, similarly to
+-mautovec-preference, or select a specific mode to be preferred.
+If both -mautovec-preference and --param=aarch64-autovec-preference are passed,
+the --param value will be used.
 
 -param=aarch64-loop-vect-issue-rate-niters=
 Target Joined UInteger Var(aarch64_loop_vect_issue_rate_niters) Init(6) 
IntegerRange(0, 65536) Param
diff --git a/gcc/doc/params.texi b/gcc/doc/params.texi
index e69be2d2923..d06589a3584 100644
--- a/gcc/doc/params.texi
+++ b/gcc/doc/params.texi
@@ -2023,9 +2023,11 @@ approximation is enabled.  The default value is 2.
 
 @paindex aarch64-autovec-preference
 @item aarch64-autovec-preference
-An old alias for @option{-mautovec-preference}.  If both
-@option{-mautovec-preference} and @option{--param=aarch64-autovec-preference}
-are passed, the @option{--param} value is used.
+Force an ISA selection strategy for auto-vectorization, similarly to
+@option{-mautovec-preference}, or select a specific machine mode to be
+used for vectorization.  If both @option{-mautovec-preference} and
+@option{--param=aarch64-autovec-preference} are passed, the @option{--param}
+value is used.
 
 @paindex aarch64-ldp-policy
 @item aarch64-ldp-policy
-- 
2.43.0

Reply via email to