Reorder arguments to vaeseq_u8 to improve AArch64 performance

The register arguments to the AESE instruction are commutative, however
the first input register is constrained in that it also names the output
register. The constraint on register allocation causes recent LLVM
versions to emit a lot of MOV instructions, significantly impacting
performance.

Swapping the register operands allows the compiler to emit significantly
fewer MOV instructions. This change improves performance on Arm
infrastructure micro-architectures by 14-36% depending on the
micro-architecture

Found and reported by George Steed from ARM. Thanks!
This commit is contained in:
Frank Denis
2025-05-21 23:04:26 +02:00
parent 3e12b517ee
commit 8466abb280
2 changed files with 2 additions and 2 deletions
@@ -40,7 +40,7 @@ typedef uint8x16_t aes_block_t;
#define AES_BLOCK_LOAD(A) vld1q_u8(A)
#define AES_BLOCK_LOAD_64x2(A, B) vreinterpretq_u8_u64(vsetq_lane_u64((A), vmovq_n_u64(B), 1))
#define AES_BLOCK_STORE(A, B) vst1q_u8((A), (B))
#define AES_ENC(A, B) veorq_u8(vaesmcq_u8(vaeseq_u8((A), vmovq_n_u8(0))), (B))
#define AES_ENC(A, B) veorq_u8(vaesmcq_u8(vaeseq_u8(vmovq_n_u8(0), (A))), (B))
static inline void
aegis128l_update(aes_block_t *const state, const aes_block_t d1, const aes_block_t d2)
@@ -40,7 +40,7 @@ typedef uint8x16_t aes_block_t;
#define AES_BLOCK_LOAD(A) vld1q_u8(A)
#define AES_BLOCK_LOAD_64x2(A, B) vreinterpretq_u8_u64(vsetq_lane_u64((A), vmovq_n_u64(B), 1))
#define AES_BLOCK_STORE(A, B) vst1q_u8((A), (B))
#define AES_ENC(A, B) veorq_u8(vaesmcq_u8(vaeseq_u8((A), vmovq_n_u8(0))), (B))
#define AES_ENC(A, B) veorq_u8(vaesmcq_u8(vaeseq_u8(vmovq_n_u8(0), (A))), (B))
static inline void
aegis256_update(aes_block_t *const state, const aes_block_t d)