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
>