On Fri, Nov 14, 2025 at 01:53:05PM +0000, Alfie Richards wrote:
> Adds the AARCH64_OPT_EXTENSION_ALIAS macro to aarch64-option-extensions.def
> to define architecture features which gate no features themselves, but
> act as aliases for other features.
> 
> When getting the extension string for some architecture flags, alias features
> should be used over their constituent features, even if some of the 
> constituent
> features are enabled transitively by other features.
> 
> Changes +crypto option to use this macro.
> 
> gcc/ChangeLog:
> 
>       * common/config/aarch64/aarch64-common.cc (struct aarch64_alias_info):
>       New struct.
>       (alias_extensions): New definition.
>       (AARCH64_OPT_EXTENSION): New macro def.
>       (AARCH64_OPT_EXTENSION_ALIAS): New macro def.
>       (aarch64_get_extension_string_for_isa_flags): Update to use alias
>       extensions over constituent extensions.
>       * config/aarch64/aarch64-feature-deps.h (alias_flags): New variable
>       (AARCH64_OPT_EXTENSION): New macro def.
>       (AARCH64_OPT_EXTENSION_ALIAS): New macro def.
>       (HANDLE): Update to use alias_flags.
>       (AARCH64_CORE): Update to use alias_flags.
>       * config/aarch64/aarch64-option-extensions.def
>       (AARCH64_OPT_EXTENSION_ALIAS): New macro def.
>       (crypto): Update to us AARCH64_OPT_EXTENSION_ALIAS.
>       * config/aarch64/aarch64.h: Undef macros after use.
> ---
>  gcc/common/config/aarch64/aarch64-common.cc   | 66 ++++++++++++++-----
>  gcc/config/aarch64/aarch64-feature-deps.h     | 27 +++++++-
>  .../aarch64/aarch64-option-extensions.def     | 21 ++++--
>  gcc/config/aarch64/aarch64.h                  |  2 +
>  4 files changed, 93 insertions(+), 23 deletions(-)
> 
> diff --git a/gcc/common/config/aarch64/aarch64-common.cc 
> b/gcc/common/config/aarch64/aarch64-common.cc
> index 1488697c6ce..424809d6c6a 100644
> --- a/gcc/common/config/aarch64/aarch64-common.cc
> +++ b/gcc/common/config/aarch64/aarch64-common.cc
> @@ -178,6 +178,27 @@ static constexpr aarch64_extension_info all_extensions[] 
> =
>    {NULL, 0, 0, 0, 0}
>  };
>  
> +struct aarch64_alias_info
> +{
> +  /* The canonical feature bit for this alias.  */
> +  aarch64_feature_flags flag_canonical;
> +  /* The set of feature bits this alias is equivalent to.  */
> +  aarch64_feature_flags flags_alias;
I've found this name to be a little confusing - perhaps aliased_flags would be
better?

However, this might not be necessary, since we could just use flags_on (none of
the logic cares about whether we've included the recursive dependencies) - this
avoids the extra definition in aarch64-feature-deps.h.

> +  /* The set of feature bits this alias is prefered over.  */
> +  aarch64_feature_flags flags_prefered_over;
> +};
> +
> +static constexpr aarch64_alias_info alias_extensions[] =
> +{
> +#define AARCH64_OPT_EXTENSION(A, B, C, D, E, F)
> +#define AARCH64_OPT_EXTENSION_ALIAS(A, IDENT, C, D, E, F, G) \
> +  {AARCH64_FL_##IDENT,\
> +   feature_deps::alias_flags_##IDENT,\
> +   feature_deps::alias_prefer_over_flags_##IDENT },
> +#include "config/aarch64/aarch64-option-extensions.def"
> +  {0, 0, 0}
> +};
> +
>  struct aarch64_arch_info
>  {
>    const char *name;
> @@ -634,10 +655,10 @@ aarch64_get_extension_string_for_isa_flags
>  {
>    std::string outstr = "";
>  
> -  /* The CRYPTO bit should only be used to support the +crypto alias
> +  /* The alias bits should only be used to support the aliases
>       during option processing, and should be cleared at all other times.
>       Verify this property for the supplied flags bitmask.  */
> -  gcc_assert (!(AARCH64_FL_CRYPTO & aarch64_isa_flags));
> +  gcc_assert (!(feature_deps::alias_flags & aarch64_isa_flags));
>    aarch64_feature_flags current_flags = default_arch_flags;
>  
>    /* As a special case, do not assume that the assembler will enable CRC
> @@ -657,24 +678,32 @@ aarch64_get_extension_string_for_isa_flags
>       But in order to make the output more readable, it seems better
>       to add the strings in definition order.  */
>    aarch64_feature_flags added = 0;
> -  auto flags_crypto = AARCH64_FL_AES | AARCH64_FL_SHA2;
>    for (unsigned int i = ARRAY_SIZE (all_extensions); i-- > 0; )
>      {
>        auto &opt = all_extensions[i];
>  
> -      /* As a special case, emit +crypto rather than +aes+sha2,
> -      in order to support assemblers that predate the separate
> -      per-feature crypto flags.  */
> -      auto flags = opt.flag_canonical;
> -      if (flags == AARCH64_FL_CRYPTO)
> -     flags = flags_crypto;
> +      bool is_alias = false;
> +      for (auto alias : alias_extensions)
> +     if (alias.flag_canonical == opt.flag_canonical)
> +       is_alias = true;

I think we should do this without looping over all aliases.  We could either do
a bitwise comparison against the alias flags mask, or we could add a field to
aarch64_extension_info to record the preferred_over value and only use the
alias logic when preferred_over is nonzero.

>  
> -      if ((flags & isa_flags & (explicit_flags | ~current_flags)) == flags)
> +      if (!is_alias
> +       && (opt.flag_canonical & isa_flags & (explicit_flags | 
> ~current_flags)) == opt.flag_canonical)
>       {
>         current_flags |= opt.flags_on;
>         added |= opt.flag_canonical;
>       }
>      }
> +
> +  /* Replace any aliased extensions.  */
> +  for (aarch64_alias_info alias : alias_extensions)
> +    if ((added & alias.flags_prefered_over) == alias.flags_prefered_over
> +     && (alias.flags_alias | isa_flags) == isa_flags)
> +      {
> +     added &= ~alias.flags_alias;
> +     added |= alias.flag_canonical;
> +      }
> +
>    for (auto &opt : all_extensions)
>      if (added & opt.flag_canonical)
>        {
> @@ -695,14 +724,19 @@ aarch64_get_extension_string_for_isa_flags
>        separate per-feature crypto flags.  Only allow "+nocrypto" when "sm4"
>        is not already enabled (to avoid dependending on whether "+nocrypto"
>        also disables "sm4").  */
> -      if (flags & flags_crypto
> -       && (flags_crypto & current_flags & ~isa_flags) == flags_crypto
> +      if (flags & feature_deps::alias_flags_CRYPTO
> +       && (feature_deps::alias_flags_CRYPTO & current_flags & ~isa_flags)
> +            == feature_deps::alias_flags_CRYPTO
>         && !(current_flags & AARCH64_FL_SM4))
> -       continue;
> +     continue;
>  
> -      if (flags == AARCH64_FL_CRYPTO)
> -     /* If either crypto flag needs removing here, then both do.  */
> -     flags = flags_crypto;
> +      /* Emit +noALIAS instead of +noX+noY where X and Y are the consituent
> +      extensions of the alias.  */
> +      for (auto alias : alias_extensions)
> +     {
> +       if (opt.flag_canonical == alias.flag_canonical)
> +         flags = alias.flags_alias;
> +     }

This logic (including the existing crypto handling) would work better as a
separate post-processing loop.  I think the current processing order means that
the aliases are checked only after the aliased flags have been processed, so
would never be used.

>  
>        if (flags & current_flags & ~isa_flags)
>       {
> diff --git a/gcc/config/aarch64/aarch64-feature-deps.h 
> b/gcc/config/aarch64/aarch64-feature-deps.h
> index 55a0dbfae61..cab8680f23b 100644
> --- a/gcc/config/aarch64/aarch64-feature-deps.h
> +++ b/gcc/config/aarch64/aarch64-feature-deps.h
> @@ -66,12 +66,20 @@ get_enable (T1 i, Ts... args)
>     files are in topological order.  */
>  template<aarch64_feature> struct info;
>  
> +  constexpr auto alias_flags = aarch64_feature_flags (0)
> +#define AARCH64_OPT_EXTENSION_ALIAS(A, IDENT, C, D, E, F, G) | 
> AARCH64_FL_##IDENT
> +#define AARCH64_OPT_EXTENSION(A, IDENT, C, D, E, F)
> +#include "config/aarch64/aarch64-option-extensions.def"
> +;
> +#undef AARCH64_OPT_EXTENSION_ALIAS
> +#undef AARCH64_OPT_EXTENSION
> +
>  #define HANDLE(IDENT, REQUIRES, EXPLICIT_ON)                         \
>    template<> struct info<aarch64_feature::IDENT> {                   \
>      static constexpr auto flag = AARCH64_FL_##IDENT;                 \
>      static constexpr auto enable = flag | get_enable REQUIRES;               
> \
> -    static constexpr auto explicit_on                                   \
> -      = (enable | get_enable EXPLICIT_ON) & ~AARCH64_FL_CRYPTO;         \
> +    static constexpr auto explicit_on                                        
> \
> +      = (enable | get_enable EXPLICIT_ON) & ~alias_flags;            \
>    };                                                                 \
>    constexpr aarch64_feature_flags info<aarch64_feature::IDENT>::flag;        
> \
>    constexpr aarch64_feature_flags info<aarch64_feature::IDENT>::enable;      
> \
> @@ -86,6 +94,7 @@ template<aarch64_feature> struct info;
>  #include "config/aarch64/aarch64-option-extensions.def"
>  #include "config/aarch64/aarch64-arches.def"
>  #undef HANDLE
> +#undef AARCH64_OPT_EXTENSION
>  
>  /* Return the set of all features that would need to be disabled if
>     the features in MASK are disabled.
> @@ -106,6 +115,7 @@ get_flags_off (aarch64_feature_flags mask)
>  #include "config/aarch64/aarch64-option-extensions.def"
>         );
>  }
> +#undef AARCH64_OPT_EXTENSION
>  
>  /* Define root_off_<IDENT> variables for each feature, giving the set of
>     features that must be turned off by +noIDENT.  This set is not 
> transitively
> @@ -114,13 +124,14 @@ get_flags_off (aarch64_feature_flags mask)
>    constexpr auto root_off_##IDENT \
>      = AARCH64_FL_##IDENT | get_flags EXPLICIT_OFF;
>  #include "config/aarch64/aarch64-option-extensions.def"
> +#undef AARCH64_OPT_EXTENSION
>  
>  /* Define cpu_<NAME> variables for each CPU, giving the transitive
>     closure of all the features that the CPU supports.  The CRYPTO bit is just

This comment needs updating.

>     an alias, so explicitly unset it for consistency.  */
>  #define AARCH64_CORE(A, CORE_IDENT, C, ARCH_IDENT, FEATURES, F, G, H, I) \
>    constexpr auto cpu_##CORE_IDENT \
> -    = (ARCH_IDENT ().enable | get_enable FEATURES) & ~AARCH64_FL_CRYPTO;
> +    = (ARCH_IDENT ().enable | get_enable FEATURES) & ~alias_flags;
>  #include "config/aarch64/aarch64-cores.def"
>  
>  /* Define fmv_deps_<NAME> variables for each FMV feature, giving the 
> transitive
> @@ -128,8 +139,18 @@ get_flags_off (aarch64_feature_flags mask)
>  #define AARCH64_FMV_FEATURE(A, FEAT_NAME, OPT_FLAGS) \
>    constexpr auto fmv_deps_##FEAT_NAME = get_enable OPT_FLAGS;
>  #include "config/aarch64/aarch64-option-extensions.def"
> +#undef AARCH64_FMV_FEATURE
>  
> +#define AARCH64_OPT_EXTENSION_ALIAS(A, IDENT, OPT_FLAGS, D, E, \
> +                                 PREFER_FLAGS, G) \
> +  constexpr auto alias_flags_##IDENT = get_flags OPT_FLAGS;\
> +  constexpr auto alias_prefer_over_flags_##IDENT = get_flags PREFER_FLAGS;
>  
> +#define AARCH64_OPT_EXTENSION(A, IDENT, C, D, E, F)
> +#include "config/aarch64/aarch64-option-extensions.def"
> +;
> +#undef AARCH64_OPT_EXTENSION_ALIAS
> +#undef AARCH64_OPT_EXTENSION
>  }
>  }
>  
> diff --git a/gcc/config/aarch64/aarch64-option-extensions.def 
> b/gcc/config/aarch64/aarch64-option-extensions.def
> index 083515d890d..9d1d7166b17 100644
> --- a/gcc/config/aarch64/aarch64-option-extensions.def
> +++ b/gcc/config/aarch64/aarch64-option-extensions.def
> @@ -25,6 +25,9 @@
>        AARCH64_OPT_EXTENSION(NAME, IDENT, REQUIRES, EXPLICIT_ON,
>                           EXPLICIT_OFF, FEATURE_STRING)
>  
> +      AARCH64_OPT_EXTENSION_ALIAS(NAME, IDENT, REQUIRES, EXPLICIT_ON,
> +                               EXPLICIT_OFF, PREFER_OVER, FEATURE_STRING)
> +
>        AARCH64_FMV_FEATURE(NAME, FEAT_NAME, IDENT)
>  
>     - NAME is the name of the extension, represented as a string constant.
> @@ -66,6 +69,10 @@
>     - OPT_FLAGS is a list of feature IDENTS that should be enabled (along with
>       their transitive dependencies) when the specified FMV feature is 
> present.
>  
> +   - PREFER_OVER is a list of features that need to be present when emitting
> +     the list of architecture feature options for the alias option to be
> +     preferred instead.
> +
>     Where a feature is present as both an extension and a function
>     multiversioning feature, and IDENT matches the FEAT_NAME suffix, then 
> these
>     can be listed here simultaneously using the macro:
> @@ -88,6 +95,13 @@
>                             EXPLICIT_OFF, FEATURE_STRING)
>  #endif
>  
> +#ifndef AARCH64_OPT_EXTENSION_ALIAS
> +#define AARCH64_OPT_EXTENSION_ALIAS(NAME, IDENT, REQUIRES, EXPLICIT_ON, \
> +                                 EXPLICIT_OFF, PREFERRED_OVER, 
> FEATURE_STRING) \
> +AARCH64_OPT_EXTENSION(NAME, IDENT, REQUIRES, EXPLICIT_ON, EXPLICIT_OFF, \
> +                   FEATURE_STRING)
> +#endif
> +
>  #ifndef AARCH64_FMV_FEATURE
>  #define AARCH64_FMV_FEATURE(NAME, FEAT_NAME, OPT_FLAGS)
>  #endif
> @@ -134,11 +148,9 @@ AARCH64_FMV_FEATURE("aes", PMULL, (AES))
>  
>  /* +nocrypto disables AES, SHA2 and SM4, and anything that depends on them
>     (such as SHA3 and the SVE2 crypto extensions).  */
> -AARCH64_OPT_EXTENSION("crypto", CRYPTO, (AES, SHA2), (), (AES, SHA2, SM4),
> -                   "aes pmull sha1 sha2")
> +AARCH64_OPT_EXTENSION_ALIAS("crypto", CRYPTO, (AES, SHA2), (), (AES, SHA2, 
> SM4),
> +                         (AES, SHA2), "aes pmull sha1 sha2")
>  
> -/* Listing sha3 after crypto means we pass "+aes+sha3" to the assembler
> -   instead of "+sha3+crypto".  */
>  AARCH64_OPT_EXTENSION("sha3", SHA3, (SHA2), (), (), "sha3 sha512")
>  
>  /* +nofp16 disables an implicit F16FML, even though an implicit F16FML
> @@ -291,4 +303,5 @@ AARCH64_OPT_EXTENSION("cpa", CPA, (), (), (), "")
>  
>  #undef AARCH64_OPT_FMV_EXTENSION
>  #undef AARCH64_OPT_EXTENSION
> +#undef AARCH64_OPT_EXTENSION_ALIAS
>  #undef AARCH64_FMV_FEATURE
> diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
> index 0e596b59744..ad5b128092b 100644
> --- a/gcc/config/aarch64/aarch64.h
> +++ b/gcc/config/aarch64/aarch64.h
> @@ -179,6 +179,8 @@ enum class aarch64_feature : unsigned char {
>  #include "aarch64-option-extensions.def"
>  #include "aarch64-arches.def"
>  #undef HANDLE
> +#undef AARCH64_OPT_EXTENSION
> +#undef AARCH64_ARCH
>  
>  /* Define aarch64_isa_mode masks.  */
>  #define DEF_AARCH64_ISA_MODE(IDENT) \
> -- 
> 2.34.1
> 

Reply via email to