On Fri, Mar 13, 2026 at 03:23:44PM +0000, Sivan Shani wrote:
> This patch adds support for the SVE_AES2 and SSVE_AES extensions,
> including the following new instructions:
>
> - PMULL (multi-vector, outputting to a pair of vectors)
> - PMLAL (multi-vector, accumulating into a pair of vectors)
> - AESE (indexed, two and four register variants)
> - AESD (indexed, two and four register variants)
> - AESEMC (indexed, two and four register variants)
> - AESDIMC (indexed, two and four register variants)
>
> It also makes the existing SVE2 AES instructions (AESE, AESD, AESMC,
> AESIMC, PMULLB, PMULLT and their pair variants) available in streaming
> SVE mode when SSVE_AES is enabled.
>
I think this should be two separate patches - one to adjust the gating for the
existing instructions to fully support +ssve-aes, and one to add the new
FEAT_SVE_AES2 instructions.
...
> diff --git a/gcc/config/aarch64/aarch64-c.cc b/gcc/config/aarch64/aarch64-c.cc
> index a55028dcd0a..4874ab4acf4 100644
> --- a/gcc/config/aarch64/aarch64-c.cc
> +++ b/gcc/config/aarch64/aarch64-c.cc
> @@ -225,6 +225,7 @@ aarch64_update_cpp_builtins (cpp_reader *pfile)
> "__ARM_FEATURE_SVE_B16B16", pfile);
> aarch64_def_or_undef (TARGET_SVE2, "__ARM_FEATURE_SVE2", pfile);
> aarch64_def_or_undef (TARGET_SVE2_AES, "__ARM_FEATURE_SVE2_AES", pfile);
> + aarch64_def_or_undef (TARGET_SVE_AES2, "__ARM_FEATURE_SVE_AES2", pfile);
This should probably use an explicit AARCH64_HAVE_ISA check to avoid depending
on whether streaming mode is enabled or not when the macro is used.
> aarch64_def_or_undef (TARGET_SVE2_BITPERM,
> "__ARM_FEATURE_SVE2_BITPERM", pfile);
> aarch64_def_or_undef (TARGET_SVE2_SHA3, "__ARM_FEATURE_SVE2_SHA3", pfile);
> @@ -320,6 +321,8 @@ aarch64_update_cpp_builtins (cpp_reader *pfile)
> "__ARM_FEATURE_SSVE_BITPERM", pfile);
> aarch64_def_or_undef (AARCH64_HAVE_ISA (SSVE_FEXPA),
> "__ARM_FEATURE_SSVE_FEXPA", pfile);
> + aarch64_def_or_undef (AARCH64_HAVE_ISA (SSVE_AES),
> "__ARM_FEATURE_SSVE_AES",
> + pfile);
>
> // Function multi-versioning defines
> aarch64_def_or_undef (targetm.has_ifunc_p (),
...
> diff --git a/gcc/config/aarch64/aarch64-sve-builtins-sve2.def
> b/gcc/config/aarch64/aarch64-sve-builtins-sve2.def
> index 1a55de890cf..47f01a19c2e 100644
> --- a/gcc/config/aarch64/aarch64-sve-builtins-sve2.def
> +++ b/gcc/config/aarch64/aarch64-sve-builtins-sve2.def
> @@ -195,8 +195,8 @@ DEF_SVE_FUNCTION (svstnt1w_scatter,
> store_scatter_index_restricted, d_integer, i
> DEF_SVE_FUNCTION (svstnt1w_scatter, store_scatter_offset_restricted,
> d_integer, implicit)
> #undef REQUIRED_EXTENSIONS
>
> -#define REQUIRED_EXTENSIONS nonstreaming_sve (AARCH64_FL_SVE2 \
> - | AARCH64_FL_SVE_AES)
> +#define REQUIRED_EXTENSIONS streaming_compatible (AARCH64_FL_SVE2 \
> + | AARCH64_FL_SVE_AES, AARCH64_FL_SSVE_AES)
> DEF_SVE_FUNCTION (svaesd, binary, b_unsigned, none)
> DEF_SVE_FUNCTION (svaese, binary, b_unsigned, none)
> DEF_SVE_FUNCTION (svaesimc, unary, b_unsigned, none)
> @@ -205,6 +205,16 @@ DEF_SVE_FUNCTION (svpmullb_pair, binary_opt_n,
> d_unsigned, none)
> DEF_SVE_FUNCTION (svpmullt_pair, binary_opt_n, d_unsigned, none)
> #undef REQUIRED_EXTENSIONS
>
> +#define REQUIRED_EXTENSIONS \
> + streaming_compatible (AARCH64_FL_SVE_AES2, AARCH64_FL_SSVE_AES)
This gating is wrong - it should be
+ streaming_compatible (AARCH64_FL_SVE_AES2 | AARCH64_FL_SVE2,
AARCH64_FL_SVE_AES2 | AARCH64_FL_SSVE_AES)
> +DEF_SVE_FUNCTION_GS (svaese_lane, binary_aes_lane, b_unsigned, x24, none)
> +DEF_SVE_FUNCTION_GS (svaesd_lane, binary_aes_lane, b_unsigned, x24, none)
> +DEF_SVE_FUNCTION_GS (svaesemc_lane, binary_aes_lane, b_unsigned, x24, none)
> +DEF_SVE_FUNCTION_GS (svaesdimc_lane, binary_aes_lane, b_unsigned, x24, none)
> +DEF_SVE_FUNCTION_GS (svpmull_pair, binary_tuple_uint64_n, d_unsigned, x2,
> none)
> +DEF_SVE_FUNCTION_GS (svpmlal_pair, ternary_tuple_uint64_n, d_unsigned, x2,
> none)
> +#undef REQUIRED_EXTENSIONS
> +
> #define REQUIRED_EXTENSIONS streaming_compatible (AARCH64_FL_SVE2 \
> | AARCH64_FL_SVE_BITPERM, \
> AARCH64_FL_SSVE_BITPERM)
...
> diff --git a/gcc/config/aarch64/aarch64-sve2.md
> b/gcc/config/aarch64/aarch64-sve2.md
> index 1970f882bfe..1f1a2c919bf 100644
> --- a/gcc/config/aarch64/aarch64-sve2.md
> +++ b/gcc/config/aarch64/aarch64-sve2.md
> @@ -4062,6 +4062,8 @@ (define_insn "*cond_<sve_fp_op><mode>_strict"
> ;; - PMUL
> ;; - PMULLB
> ;; - PMULLT
> +;; - PMULL
> +;; - PMLAL
> ;; -------------------------------------------------------------------------
>
> ;; Uniform PMUL.
> @@ -4084,7 +4086,7 @@ (define_insn "@aarch64_sve_<optab><mode>"
> [(match_operand:<VNARROW> 1 "register_operand" "w")
> (match_operand:<VNARROW> 2 "register_operand" "w")]
> SVE2_PMULL))]
> - "TARGET_SVE2"
> + "TARGET_SSVE2_AES"
Why are you changing this?
> "<sve_int_op>\t%0.<Vetype>, %1.<Ventype>, %2.<Ventype>"
> [(set_attr "sve_type" "sve_int_pmul")]
> )
> @@ -4098,11 +4100,46 @@ (define_insn "@aarch64_sve_<optab><mode>"
> [(match_operand:SVE2_PMULL_PAIR_I 1 "register_operand" "w")
> (match_operand:SVE2_PMULL_PAIR_I 2 "register_operand" "w")]
> SVE2_PMULL_PAIR))]
> - "TARGET_SVE2"
> + "TARGET_SSVE2_AES"
Ditto?
> "<sve_int_op>\t%0.<Vewtype>, %1.<Vetype>, %2.<Vetype>"
> [(set_attr "sve_type" "sve_int_pmul")]
> )
>
> +;; Output to a tuple of vectors.
> +;; PMULL { <Zd1>.Q-<Zd2>.Q }, <Zn>.D, <Zm>.D
> +;; <Zd1> must be a multiple of 2 (0, 2, ..., 30)
> +;; <Zd2> must be must be Zdn1 + 1
> +;; <Zn> (0-31) scalable vector
> +;; <Zm> (0-31) scalable vector -or- an uint64 (broadcast to a vector)
> +(define_insn "aarch64_sve_pmull_pair"
> + [(set (match_operand:VNx4DI 0 "aligned_register_operand" "=Uw2")
> + (unspec:VNx4DI
> + [(match_operand:VNx2DI 1 "register_operand" "w")
> + (match_operand:VNx2DI 2 "register_operand" "w")]
> + UNSPEC_PMULL_PAIR))]
> + "TARGET_SSVE_AES"
> + "pmull\t{%S0.q - %T0.q}, %1.d, %2.d"
> + [(set_attr "sve_type" "sve_int_pmul")]
> +)
It would be nice if we could also form this instruction by combining a pmullb
and pmullt instruction, but I'm not familiar with how we would do that.
> +
> +;; Output to a tuple of vectors, accumulating.
> +;; PMLAL { <Zda1>.Q-<Zda2>.Q }, <Zn>.D, <Zm>.D
> +;; <Zda1> must be a multiple of 2 (0, 2, ..., 30)
> +;; <Zda2> must be must be Zdn1 + 1
> +;; <Zn> (0-31) scalable vector
> +;; <Zm> (0-31) scalable vector -or- an uint64 (broadcast to a vector)
> +(define_insn "aarch64_sve_pmlal_pair"
> + [(set (match_operand:VNx4DI 0 "aligned_register_operand" "=Uw2")
> + (unspec:VNx4DI
> + [(match_operand:VNx4DI 1 "aligned_register_operand" "0")
> + (match_operand:VNx2DI 2 "register_operand" "w")
> + (match_operand:VNx2DI 3 "register_operand" "w")]
> + UNSPEC_PMLAL_PAIR))]
> + "TARGET_SSVE_AES"
> + "pmlal\t{%S0.q - %T0.q}, %2.d, %3.d"
> + [(set_attr "sve_type" "sve_int_pmul")]
> +)
> +
> ;; =========================================================================
> ;; == Comparisons and selects
> ;; =========================================================================
> @@ -4709,6 +4746,10 @@ (define_insn "@aarch64_sve_luti<LUTI_BITS><mode>"
> ;; - AESE
> ;; - AESIMC
> ;; - AESMC
> +;; - AESD (indexed, two registers and four registers)
> +;; - AESE (indexed, two registers and four registers)
> +;; - AESEMC (indexed, two registers and four registers)
> +;; - AESDIMC (indexed, two registers and four registers)
> ;; -------------------------------------------------------------------------
>
> ;; AESD and AESE.
> @@ -4719,7 +4760,7 @@ (define_insn "aarch64_sve2_aes<aes_op>"
> (match_operand:VNx16QI 1 "register_operand" "%0")
> (match_operand:VNx16QI 2 "register_operand" "w"))]
> CRYPTO_AES))]
> - "TARGET_SVE2_AES"
> + "TARGET_SSVE2_AES"
> "aes<aes_op>\t%0.b, %0.b, %2.b"
> [(set_attr "type" "crypto_aese")]
> )
> @@ -4730,7 +4771,7 @@ (define_insn "aarch64_sve2_aes<aesmc_op>"
> (unspec:VNx16QI
> [(match_operand:VNx16QI 1 "register_operand" "0")]
> CRYPTO_AESMC))]
> - "TARGET_SVE2_AES"
> + "TARGET_SSVE2_AES"
> "aes<aesmc_op>\t%0.b, %0.b"
> [(set_attr "type" "crypto_aesmc")]
> )
> @@ -4749,7 +4790,7 @@ (define_insn "*aarch64_sve2_aese_fused"
> (match_operand:VNx16QI 2 "register_operand" "w"))]
> UNSPEC_AESE)]
> UNSPEC_AESMC))]
> - "TARGET_SVE2_AES && aarch64_fusion_enabled_p (AARCH64_FUSE_AES_AESMC)"
> + "TARGET_SSVE2_AES && aarch64_fusion_enabled_p (AARCH64_FUSE_AES_AESMC)"
> "aese\t%0.b, %0.b, %2.b\;aesmc\t%0.b, %0.b"
> [(set_attr "type" "crypto_aese")
> (set_attr "length" "8")]
> @@ -4764,12 +4805,49 @@ (define_insn "*aarch64_sve2_aesd_fused"
> (match_operand:VNx16QI 2 "register_operand" "w"))]
> UNSPEC_AESD)]
> UNSPEC_AESIMC))]
> - "TARGET_SVE2_AES && aarch64_fusion_enabled_p (AARCH64_FUSE_AES_AESMC)"
> + "TARGET_SSVE2_AES && aarch64_fusion_enabled_p (AARCH64_FUSE_AES_AESMC)"
> "aesd\t%0.b, %0.b, %2.b\;aesimc\t%0.b, %0.b"
> [(set_attr "type" "crypto_aese")
> (set_attr "length" "8")]
> )
>
> +;; AESE and AESD, indexed, two registers and four registers.
> +;; AES<E/D> { <Zdn1>.B-<Zdn(2/4)>.B }, { <Zdn1>.B-<Zdn(2/4)>.B },
> <Zm>.Q[<index>]
> +;; <Zdn1> must be a multiple of 2 (0, 2, ..., 30) or 4 (0, 4, ..., 28)
> +;; <Zdn4> must be must be Zdn1 + 1 or Zdn1 + 3
> +;; <Zm> (0-31)
> +;; <Index> (0-3)
> +
> +(define_insn "@aarch64_sve2_aes<aes_op>_lane<mode>"
> + [(set (match_operand:SVE_QIx24 0 "aligned_register_operand"
> "=Uw<vector_count>")
> + (unspec:SVE_QIx24
> + [(match_operand:SVE_QIx24 1 "aligned_register_operand" "0")
> + (match_operand:VNx16QI 2 "register_operand" "w")
> + (match_operand:SI 3 "const_0_to_3_operand")]
> + CRYPTO_AES))]
This usage of UNSPEC_AESD/UNSPEC_AESE is inconsistent with the existing usage
in two ways:
- the existing uses take an single vector operand, with the xor part of the
operation separated out;
- the existing use doesn't take an indexed operand.
I think the most consistent way to handle this would be to split the operation
into three operations:
- an indexed lane selection (similar to the existing UNSPEC_SVE_LANE_SELECT,
but operating within 512-bit blocks instead of 128-bit blocks);
- an explicit xor; and
- the existing UNSPEC_AESD/UNSPEC_AESE.
The alternative would be to just define new unspecs - I'm not sure of the
trade-offs of these two approaches. It probably makes little practical
difference unless we start optimising the lane indexing for this sort of
instruction.
> + "TARGET_SSVE_AES"
> + "aes<aes_op>\t%0, %0, %2.q[%3]"
> + [(set_attr "type" "crypto_aese")]
> +)
> +
> +;; AESEMC and AESDIMC, indexed, two registers and four registers.
> +;; AESEMC/AESDIMC { <Zdn1>.B-<Zdn (2/4)>.B }, { <Zdn1>.B-<Zdn (2/4)>.B },
> <Zm>.Q[<index>]
> +;; <Zdn1> must be a multiple of 2 (0, 2, ..., 30)
> +;; <Zdn2> must be Zdn1 + 1 or Zdn1 + 3
> +;; <Zm> (0-31)
> +
> +(define_insn "@aarch64_sve2_aes<aesemc_op>_lane<mode>"
> + [(set (match_operand:SVE_QIx24 0 "aligned_register_operand"
> "=Uw<vector_count>")
> + (unspec:SVE_QIx24
> + [(match_operand:SVE_QIx24 1 "aligned_register_operand" "0")
> + (match_operand:VNx16QI 2 "register_operand" "w")
> + (match_operand:SI 3 "const_0_to_3_operand")]
> + CRYPTO_AESMCI))]
This is just the composition of the new AES[DE] (indexed) instructions with a
multivector version of the existing AESIMC/AESMC instruction, so I think the
best way to represent it would be to copy the representation for the previous
new operation and then apply UNSPEC_AESIMC/UNSPEC_AESMC to the result.
> + "TARGET_SSVE_AES"
> + "aes<aesemc_op>\t%0, %0, %2.q[%3]"
> + [(set_attr "type" "crypto_aesmc")]
> +)
> +
> ;; -------------------------------------------------------------------------
> ;; ---- Optional SHA-3 extensions
> ;; -------------------------------------------------------------------------
> diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
> index 0a53b42b199..7a411ad9b76 100644
> --- a/gcc/config/aarch64/aarch64.h
> +++ b/gcc/config/aarch64/aarch64.h
> @@ -292,8 +292,21 @@ constexpr auto AARCH64_FL_DEFAULT_ISA_MODE
> ATTRIBUTE_UNUSED
>
> /* SVE2 AES instructions, enabled through +sve2-aes. */
> #define TARGET_SVE2_AES (AARCH64_HAVE_ISA (SVE2) \
> - && AARCH64_HAVE_ISA (SVE_AES) \
> - && TARGET_NON_STREAMING)
> + && AARCH64_HAVE_ISA (SVE_AES))
> +
> +/* SVE2 AES instructions enabled through +sve-aes2 for non-streaming
> + and +ssve-aes for streaming. */
> +#define TARGET_SSVE2_AES ((TARGET_SVE2_AES) \
> + && (AARCH64_HAVE_ISA (SSVE_AES) || TARGET_NON_STREAMING))
> +
> +/* sve_aes2 instructions are enabled through +sve-aes2. */
> +#define TARGET_SVE_AES2 (AARCH64_HAVE_ISA (SVE2) \
> + && AARCH64_HAVE_ISA (SVE_AES2))
> +
> +/* SVE AES2 instructions enabled through +sve-aes2 for non-streaming
> + and +ssve-aes for streaming. */
> +#define TARGET_SSVE_AES ((TARGET_SVE_AES2) \
> + && (AARCH64_HAVE_ISA (SSVE_AES) || TARGET_NON_STREAMING))
These definitions are wrong, and TARGET_SSVE2_AES is a confusing name. I think
it would be better to replace all these TARGET_* macros (including the existing
TARGET_SVE2_AES one) with just the following two:
#define TARGET_SVE_AES (AARCH64_HAVE_ISA (SVE_AES) \
&& (AARCH64_HAVE_ISA (SVE2) || TARGET_STREAMING) \
&& (AARCH64_HAVE_ISA (SSVE_AES)
|| TARGET_NON_STREAMING))
#define TARGET_SVE_AES2 (TARGET_SVE_AES && AARCH64_HAVE_ISA (SVE_AES2))
>
> /* Checks if FEAT_SVE2_BitPerm is supported which is aliased to
> SVE2 + SVE_BitPerm. */
> diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
> index a469d082bbb..7972c7a650b 100644
> --- a/gcc/config/aarch64/iterators.md
> +++ b/gcc/config/aarch64/iterators.md
> @@ -697,6 +697,9 @@ (define_mode_iterator SVE_SI [VNx2SI VNx4SI])
>
> (define_mode_iterator SVE_DIx24 [VNx4DI VNx8DI])
>
> +;; SVE integer vector modes with 2 and 4 vectors of 8-bit elements.
> +(define_mode_iterator SVE_QIx24 [VNx32QI VNx64QI])
> +
> ;; SVE modes with 2 or 4 elements.
> (define_mode_iterator SVE_24 [VNx2QI VNx2HI VNx2HF VNx2BF VNx2SI VNx2SF
> VNx2DI VNx2DF
> @@ -887,6 +890,8 @@ (define_c_enum "unspec"
> UNSPEC_SQDMULH ; Used in aarch64-simd.md.
> UNSPEC_SQRDMULH ; Used in aarch64-simd.md.
> UNSPEC_PMUL ; Used in aarch64-simd.md.
> + UNSPEC_PMULL_PAIR ; Used in aarch64-sve2.md.
> + UNSPEC_PMLAL_PAIR ; Used in aarch64-sve2.md.
> UNSPEC_FMULX ; Used in aarch64-simd.md.
> UNSPEC_USQADD ; Used in aarch64-simd.md.
> UNSPEC_SUQADD ; Used in aarch64-simd.md.
> @@ -938,6 +943,8 @@ (define_c_enum "unspec"
> UNSPEC_AESD ; Used in aarch64-simd.md.
> UNSPEC_AESMC ; Used in aarch64-simd.md.
> UNSPEC_AESIMC ; Used in aarch64-simd.md.
> + UNSPEC_AESEMC ; Used in aarch64-sve2.md.
> + UNSPEC_AESDIMC ; Used in aarch64-sve2.md.
> UNSPEC_SHA1C ; Used in aarch64-simd.md.
> UNSPEC_SHA1M ; Used in aarch64-simd.md.
> UNSPEC_SHA1P ; Used in aarch64-simd.md.
> @@ -3546,6 +3553,8 @@ (define_int_iterator CRC [UNSPEC_CRC32B UNSPEC_CRC32H
> UNSPEC_CRC32W
>
> (define_int_iterator CRYPTO_AES [UNSPEC_AESE UNSPEC_AESD])
> (define_int_iterator CRYPTO_AESMC [UNSPEC_AESMC UNSPEC_AESIMC])
> +;; Indexed versions
> +(define_int_iterator CRYPTO_AESMCI [UNSPEC_AESEMC UNSPEC_AESDIMC])
>
> (define_int_iterator CRYPTO_SHA1 [UNSPEC_SHA1C UNSPEC_SHA1M UNSPEC_SHA1P])
>
> @@ -4681,6 +4690,7 @@ (define_int_attr crc_mode [(UNSPEC_CRC32B "QI")
> (UNSPEC_CRC32H "HI")
>
> (define_int_attr aes_op [(UNSPEC_AESE "e") (UNSPEC_AESD "d")])
> (define_int_attr aesmc_op [(UNSPEC_AESMC "mc") (UNSPEC_AESIMC "imc")])
> +(define_int_attr aesemc_op [(UNSPEC_AESEMC "emc") (UNSPEC_AESDIMC "dimc")])
>
> (define_int_attr sha1_op [(UNSPEC_SHA1C "c") (UNSPEC_SHA1P "p")
> (UNSPEC_SHA1M "m")])
> diff --git a/gcc/config/aarch64/predicates.md
> b/gcc/config/aarch64/predicates.md
> index 40b0e8b9f02..89e392367a9 100644
> --- a/gcc/config/aarch64/predicates.md
> +++ b/gcc/config/aarch64/predicates.md
> @@ -50,6 +50,10 @@ (define_predicate "const0_to_1_operand"
> (and (match_code "const_int")
> (match_test "IN_RANGE (INTVAL (op), 0, 1)")))
>
> +(define_predicate "const_0_to_3_operand"
> + (and (match_code "const_int")
> + (match_test "IN_RANGE (INTVAL (op), 0, 3)")))
> +
> (define_predicate "const_0_to_7_operand"
> (and (match_code "const_int")
> (match_test "IN_RANGE (INTVAL (op), 0, 7)")))
...
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/pmullt_u16.c
> b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/pmullt_u16.c
> index 52ddb40e576..ff712082639 100644
> --- a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/pmullt_u16.c
> +++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/pmullt_u16.c
> @@ -1,7 +1,11 @@
> +/* { dg-do assemble { target aarch64_asm_ssve-aes_ok } } */
> +/* { dg-do compile { target { ! aarch64_asm_ssve-aes_ok } } } */
> /* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */
>
> #include "test_sve_acle.h"
>
> +#pragma GCC target "+sve2-aes+ssve-aes"
> +
This change (and others like it) make no sense to me - why would you change the
enabled features in an existing test, and especially when those features have
nothing to do with the instructions used?
> /*
> ** pmullt_u16_tied1:
> ** pmullt z0\.h, z0\.b, z1\.b
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/pmullt_u64.c
> b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/pmullt_u64.c
> index 0821e97e378..16db886a35c 100644
> --- a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/pmullt_u64.c
> +++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/pmullt_u64.c
> @@ -1,7 +1,11 @@
> +/* { dg-do assemble { target aarch64_asm_ssve-aes_ok } } */
> +/* { dg-do compile { target { ! aarch64_asm_ssve-aes_ok } } } */
> /* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */
>
> #include "test_sve_acle.h"
>
> +#pragma GCC target "+sve2-aes+ssve-aes"
> +
> /*
> ** pmullt_u64_tied1:
> ** pmullt z0\.d, z0\.s, z1\.s
> diff --git a/gcc/testsuite/lib/target-supports.exp
> b/gcc/testsuite/lib/target-supports.exp
> index 6ffa40fb1dd..a9c13bdb86e 100644
> --- a/gcc/testsuite/lib/target-supports.exp
> +++ b/gcc/testsuite/lib/target-supports.exp
> @@ -12750,7 +12750,7 @@ set exts_sve2 {
> "sme-f8f16" "sme-f8f32"
> "sme-b16b16" "sme-f16f16" "sme-i16i64" "sme" "sme2" "sme2p1" "sme2p2"
> "ssve-fp8dot2" "ssve-fp8dot4" "ssve-fp8fma" "sve-bfscale"
> - "sme-tmop" "ssve-fexpa" "ssve-bitperm"
> + "sme-tmop" "ssve-fexpa" "ssve-bitperm" "ssve-aes"
Why do you not also add sve-aes2 to this list? That suggests that you've gated
some assembler tests incorrectly. (Do we also need sve-aes here? Maybe not.)
> }
>
> foreach { aarch64_ext } $exts {
> --
> 2.43.0
>