https://gcc.gnu.org/g:600ca81fdaed7dc267e6f386e773b86ca9c50ce0
commit r17-4795-g600ca81fdaed7dc267e6f386e773b86ca9c50ce0 Author: Karl Meakin <[email protected]> Date: Thu Sep 24 16:52:05 2026 +0000 aarch64: Port NEON AES intrinsics to pragma-based framework Port the AES intrinsics (FEAT_AES) to the pragma-based framework and add assembly tests for each intrinsic. gcc/ChangeLog: * config/aarch64/aarch64-builtins.cc (aarch64_general_gimple_fold_builtin): Delete cases for `crypto_aese` and `crypto_aesd`. (aarch64_fold_aes_op): Delete now-unused function. * config/aarch64/aarch64-neon-builtins-base.cc (struct gimple_exact_insn): New struct. * config/aarch64/aarch64-neon-builtins-base.def (vaeseq, vaesdq, vaesmcq, vaesimcq): New function declarations. * config/aarch64/aarch64-simd-builtins.def: Delete builtin functions. * config/aarch64/arm_neon.h (vaeseq_u8, vaesdq_u8, vaesmcq_u8, vaesimcq_u8): Delete function definitions. gcc/testsuite/ChangeLog: * gcc.target/aarch64/neon/arm_neon_test.h: Set `+aes` target flag. * gcc.target/aarch64/neon/vaes.c: New test. Diff: --- gcc/config/aarch64/aarch64-builtins.cc | 29 -------------------- gcc/config/aarch64/aarch64-neon-builtins-base.cc | 15 ++++++++++ gcc/config/aarch64/aarch64-neon-builtins-base.def | 8 ++++++ gcc/config/aarch64/aarch64-simd-builtins.def | 6 ---- gcc/config/aarch64/arm_neon.h | 28 ------------------- .../gcc.target/aarch64/neon/arm_neon_test.h | 2 +- gcc/testsuite/gcc.target/aarch64/neon/vaes.c | 32 ++++++++++++++++++++++ 7 files changed, 56 insertions(+), 64 deletions(-) diff --git a/gcc/config/aarch64/aarch64-builtins.cc b/gcc/config/aarch64/aarch64-builtins.cc index 3389fc93af73..9e4b4a9d58fb 100644 --- a/gcc/config/aarch64/aarch64-builtins.cc +++ b/gcc/config/aarch64/aarch64-builtins.cc @@ -4920,30 +4920,6 @@ aarch64_set_lane (tree lhs, tree elt, tree vec, tree lane) return gimple_build_assign (lhs, BIT_INSERT_EXPR, vec, elt, bit); } -/* Fold a call to vaeseq_u8 and vaesdq_u8. - That is `vaeseq_u8 (x ^ y, 0)` gets folded - into `vaeseq_u8 (x, y)`.*/ -static gimple * -aarch64_fold_aes_op (gcall *stmt) -{ - tree arg0 = gimple_call_arg (stmt, 0); - tree arg1 = gimple_call_arg (stmt, 1); - if (integer_zerop (arg0)) - arg0 = arg1; - else if (!integer_zerop (arg1)) - return nullptr; - if (TREE_CODE (arg0) != SSA_NAME) - return nullptr; - if (!has_single_use (arg0)) - return nullptr; - auto *s = dyn_cast<gassign *> (SSA_NAME_DEF_STMT (arg0)); - if (!s || gimple_assign_rhs_code (s) != BIT_XOR_EXPR) - return nullptr; - gimple_call_set_arg (stmt, 0, gimple_assign_rhs1 (s)); - gimple_call_set_arg (stmt, 1, gimple_assign_rhs2 (s)); - return stmt; -} - /* Fold a call to vld1, given that it loads something of type TYPE. */ static gimple * aarch64_fold_load (gcall *stmt, tree type) @@ -5236,11 +5212,6 @@ aarch64_general_gimple_fold_builtin (unsigned int fcode, gcall *stmt, gimple_call_set_lhs (new_stmt, gimple_call_lhs (stmt)); break; - VAR1 (BINOPU, crypto_aese, 0, DEFAULT, v16qi) - VAR1 (BINOPU, crypto_aesd, 0, DEFAULT, v16qi) - new_stmt = aarch64_fold_aes_op (stmt); - break; - /* Lower sqrt builtins to gimple/internal function sqrt. */ BUILTIN_VHSDF_DF (UNOP, sqrt, 2, FP) new_stmt = gimple_build_call_internal (IFN_SQRT, diff --git a/gcc/config/aarch64/aarch64-neon-builtins-base.cc b/gcc/config/aarch64/aarch64-neon-builtins-base.cc index 0313eb49759e..1bf4bf33d412 100644 --- a/gcc/config/aarch64/aarch64-neon-builtins-base.cc +++ b/gcc/config/aarch64/aarch64-neon-builtins-base.cc @@ -158,6 +158,15 @@ class gimple_function_base : public function_base gimple *fold (gimple_folder &) const override { gcc_unreachable (); } }; +template <insn_code insn> struct gimple_exact_insn : gimple_function_base +{ + gimple *fold (gimple_folder &) const override { return nullptr; } + rtx expand (function_expander &e) const override + { + return e.use_exact_insn (insn); + } +}; + /* For intrinsics that map to a single GIMPLE expression with no argument preparation necessary. */ class gimple_expr : public gimple_function_base @@ -782,4 +791,10 @@ NEON_FUNCTION (vuzp, vuzpq, gimple_permute_pair, (uzp_mask<false>, uzp_mask<tr NEON_FUNCTION (vzip1, vzip1q, gimple_permute, (zip_mask<false>)) NEON_FUNCTION (vzip2, vzip2q, gimple_permute, (zip_mask<true>)) NEON_FUNCTION (vzip, vzipq, gimple_permute_pair, (zip_mask<false>, zip_mask<true>)) + +// AES +NEON_FUNCTION (vaeseq, gimple_exact_insn<CODE_FOR_aarch64_crypto_aesev16qi>,) +NEON_FUNCTION (vaesdq, gimple_exact_insn<CODE_FOR_aarch64_crypto_aesdv16qi>,) +NEON_FUNCTION (vaesmcq, gimple_exact_insn<CODE_FOR_aarch64_crypto_aesmcv16qi>,) +NEON_FUNCTION (vaesimcq, gimple_exact_insn<CODE_FOR_aarch64_crypto_aesimcv16qi>,) } diff --git a/gcc/config/aarch64/aarch64-neon-builtins-base.def b/gcc/config/aarch64/aarch64-neon-builtins-base.def index 7257f59bbc56..57d4aa6dfffb 100644 --- a/gcc/config/aarch64/aarch64-neon-builtins-base.def +++ b/gcc/config/aarch64/aarch64-neon-builtins-base.def @@ -145,3 +145,11 @@ DEF_NEON_FUNCTION (vzip2, bhs_neon, ("D0,D0,D0")) DEF_NEON_FUNCTION (vzip2q, bhsd_neon, ("Q0,Q0,Q0")) DEF_NEON_FUNCTION (vzipq, bhs_neon, ("Q0x2,Q0,Q0")) #undef REQUIRED_EXTENSIONS + +// AES +#define REQUIRED_EXTENSIONS nonstreaming_only (AARCH64_FL_SIMD | AARCH64_FL_AES) +DEF_NEON_FUNCTION (vaeseq, b_unsigned, ("Q0,Q0,Q0")) +DEF_NEON_FUNCTION (vaesdq, b_unsigned, ("Q0,Q0,Q0")) +DEF_NEON_FUNCTION (vaesmcq, b_unsigned, ("Q0,Q0")) +DEF_NEON_FUNCTION (vaesimcq, b_unsigned, ("Q0,Q0")) +#undef REQUIRED_EXTENSIONS diff --git a/gcc/config/aarch64/aarch64-simd-builtins.def b/gcc/config/aarch64/aarch64-simd-builtins.def index 9c61cc05a050..5ee19ba0cd0d 100644 --- a/gcc/config/aarch64/aarch64-simd-builtins.def +++ b/gcc/config/aarch64/aarch64-simd-builtins.def @@ -712,12 +712,6 @@ BUILTIN_VDQSF (QUADOP_LANE, float_mla_laneq, 0, FP) BUILTIN_VDQSF (QUADOP_LANE, float_mls_laneq, 0, FP) - /* Implemented by aarch64_crypto_aes<op><mode>. */ - VAR1 (BINOPU, crypto_aese, 0, DEFAULT, v16qi) - VAR1 (BINOPU, crypto_aesd, 0, DEFAULT, v16qi) - VAR1 (UNOPU, crypto_aesmc, 0, DEFAULT, v16qi) - VAR1 (UNOPU, crypto_aesimc, 0, DEFAULT, v16qi) - /* Implemented by aarch64_crypto_sha1<op><mode>. */ VAR1 (UNOPU, crypto_sha1h, 0, DEFAULT, si) VAR1 (BINOPU, crypto_sha1su1, 0, DEFAULT, v4si) diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h index 873a1195d3ed..38e33eef8137 100644 --- a/gcc/config/aarch64/arm_neon.h +++ b/gcc/config/aarch64/arm_neon.h @@ -5661,34 +5661,6 @@ vqrdmlshs_laneq_s32 (int32_t __a, int32_t __b, int32x4_t __c, const int __d) #pragma GCC target ("+nothing+aes") /* vaes */ -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vaeseq_u8 (uint8x16_t data, uint8x16_t key) -{ - return __builtin_aarch64_crypto_aesev16qi_uuu (data, key); -} - -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vaesdq_u8 (uint8x16_t data, uint8x16_t key) -{ - return __builtin_aarch64_crypto_aesdv16qi_uuu (data, key); -} - -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vaesmcq_u8 (uint8x16_t data) -{ - return __builtin_aarch64_crypto_aesmcv16qi_uu (data); -} - -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vaesimcq_u8 (uint8x16_t data) -{ - return __builtin_aarch64_crypto_aesimcv16qi_uu (data); -} - __extension__ extern __inline poly128_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vmull_p64 (poly64_t __a, poly64_t __b) diff --git a/gcc/testsuite/gcc.target/aarch64/neon/arm_neon_test.h b/gcc/testsuite/gcc.target/aarch64/neon/arm_neon_test.h index 844eef49d372..856e1a081908 100644 --- a/gcc/testsuite/gcc.target/aarch64/neon/arm_neon_test.h +++ b/gcc/testsuite/gcc.target/aarch64/neon/arm_neon_test.h @@ -1,6 +1,6 @@ #include "arm_neon.h" -#pragma GCC target "+simd+fp16+bf16+sha3" +#pragma GCC target "+simd+fp16+bf16+sha3+aes" #define VEC_LEN(VEC) (sizeof (VEC) / sizeof (VEC[0])) diff --git a/gcc/testsuite/gcc.target/aarch64/neon/vaes.c b/gcc/testsuite/gcc.target/aarch64/neon/vaes.c new file mode 100644 index 000000000000..6399dce2b3dd --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/neon/vaes.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include "arm_neon_test.h" + +/* +** test_vaeseq_u8: +** aese v0\.16b, v1\.16b +** ret +*/ +TEST_UNIFORM_BINARY (vaeseq_u8, uint8x16_t) + +/* +** test_vaesdq_u8: +** aesd v0\.16b, v1\.16b +** ret +*/ +TEST_UNIFORM_BINARY (vaesdq_u8, uint8x16_t) + +/* +** test_vaesmcq_u8: +** aesmc v0\.16b, v0\.16b +** ret +*/ +TEST_UNIFORM_UNARY (vaesmcq_u8, uint8x16_t) + +/* +** test_vaesimcq_u8: +** aesimc v0\.16b, v0\.16b +** ret +*/ +TEST_UNIFORM_UNARY (vaesimcq_u8, uint8x16_t)
