Skip to content

Commit 2cf613b

Browse files
committed
AArch64: Add compile-time guard for Neon
Previously, we assumed that every AArch64 system has Neon, and that the implementation has access to it. With this commit, use of Neon is explicitly guarded by __ARM_NEON, similar to how all use of AVX2 is guarded by __AVX2__. Signed-off-by: Hanno Becker <beckphan@amazon.co.uk>
1 parent e29c390 commit 2cf613b

29 files changed

Lines changed: 125 additions & 37 deletions

.github/workflows/ci.yml

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ jobs:
3333
arch: aarch64
3434
mode: native
3535
nix_shell: ci
36+
- runner: ubuntu-24.04-arm
37+
name: 'aarch64, no Neon'
38+
arch: aarch64
39+
mode: native
40+
nix_shell: ci
41+
cflags: '-march=armv8-a+nosimd'
42+
extra_args: '--no-auto'
3643
- runner: ubuntu-24.04-arm
3744
name: 'x86_64, cross'
3845
arch: x86_64
@@ -111,6 +118,7 @@ jobs:
111118
nix-cache: ${{ matrix.target.mode == 'native' && 'false' || 'true' }}
112119
gh_token: ${{ secrets.GITHUB_TOKEN }}
113120
compile_mode: ${{ matrix.target.mode }}
121+
cflags: ${{ matrix.target.cflags || '' }}
114122
extra_args: ${{ matrix.target.extra_args || '' }}
115123
exec_wrapper: ${{ matrix.target.exec_wrapper || '' }}
116124
opt: 'no_opt'
@@ -121,8 +129,9 @@ jobs:
121129
nix-shell: ${{ matrix.target.nix_shell }}
122130
gh_token: ${{ secrets.GITHUB_TOKEN }}
123131
compile_mode: native
124-
cflags: "-DMLKEM_DEBUG -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all"
132+
cflags: "${{ matrix.target.cflags || '' }} -DMLKEM_DEBUG -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all"
125133
ldflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all"
134+
extra_args: ${{ matrix.target.extra_args || '' }}
126135
check_namespace: 'false'
127136
- name: build + test (cross, opt)
128137
uses: ./.github/actions/multi-functest
@@ -133,6 +142,7 @@ jobs:
133142
nix-cache: ${{ matrix.target.mode == 'native' && 'false' || 'true' }}
134143
gh_token: ${{ secrets.GITHUB_TOKEN }}
135144
compile_mode: ${{ matrix.target.mode }}
145+
cflags: ${{ matrix.target.cflags || '' }}
136146
extra_args: ${{ matrix.target.extra_args || '' }}
137147
exec_wrapper: ${{ matrix.target.exec_wrapper || '' }}
138148
opt: 'opt'
@@ -147,7 +157,7 @@ jobs:
147157
compile_mode: ${{ matrix.target.mode }}
148158
extra_args: ${{ matrix.target.extra_args || '' }}
149159
exec_wrapper: ${{ matrix.target.exec_wrapper || '' }}
150-
cflags: "-DMLKEM_DEBUG"
160+
cflags: "${{ matrix.target.cflags || '' }} -DMLKEM_DEBUG"
151161
opt: 'opt'
152162
- name: build + test (cross, opt, C90)
153163
uses: ./.github/actions/multi-functest
@@ -159,7 +169,7 @@ jobs:
159169
compile_mode: ${{ matrix.target.mode }}
160170
extra_args: ${{ matrix.target.extra_args || '' }}
161171
exec_wrapper: ${{ matrix.target.exec_wrapper || '' }}
162-
cflags: "-std=c90"
172+
cflags: "${{ matrix.target.cflags || '' }} -std=c90"
163173
opt: 'opt'
164174
ppc64le_tests:
165175
if: github.repository_owner == 'pq-code-package' && !github.event.pull_request.head.repo.fork

dev/fips202/aarch64/auto.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838
#include "x1_scalar.h"
3939
#endif
4040

41+
/* Batched, SIMD-based Keccak-f1600 implementations. */
42+
#if defined(MLK_SYS_AARCH64_NEON)
43+
4144
/*
4245
* Keccak-f1600x2/x4
4346
*
@@ -70,4 +73,6 @@
7073

7174
#endif /* !__ARM_FEATURE_SHA3 */
7275

76+
#endif /* MLK_SYS_AARCH64_NEON */
77+
7378
#endif /* !MLK_DEV_FIPS202_AARCH64_AUTO_H */

mlkem/mlkem_native.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@
379379
#undef MLK_SYSV_ABI_SUPPORTED
380380
#undef MLK_SYS_AARCH64
381381
#undef MLK_SYS_AARCH64_EB
382+
#undef MLK_SYS_AARCH64_NEON
382383
#undef MLK_SYS_APPLE
383384
#undef MLK_SYS_ARMV81M_MVE
384385
#undef MLK_SYS_BIG_ENDIAN

mlkem/mlkem_native_asm.S

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@
403403
#undef MLK_SYSV_ABI_SUPPORTED
404404
#undef MLK_SYS_AARCH64
405405
#undef MLK_SYS_AARCH64_EB
406+
#undef MLK_SYS_AARCH64_NEON
406407
#undef MLK_SYS_APPLE
407408
#undef MLK_SYS_ARMV81M_MVE
408409
#undef MLK_SYS_BIG_ENDIAN

mlkem/src/fips202/native/aarch64/auto.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838
#include "x1_scalar.h"
3939
#endif
4040

41+
/* Batched, SIMD-based Keccak-f1600 implementations. */
42+
#if defined(MLK_SYS_AARCH64_NEON)
43+
4144
/*
4245
* Keccak-f1600x2/x4
4346
*
@@ -70,4 +73,6 @@
7073

7174
#endif /* !__ARM_FEATURE_SHA3 */
7275

76+
#endif /* MLK_SYS_AARCH64_NEON */
77+
7378
#endif /* !MLK_FIPS202_NATIVE_AARCH64_AUTO_H */

mlkem/src/native/meta.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*/
1111
#include "../sys.h"
1212

13-
#ifdef MLK_SYS_AARCH64
13+
#ifdef MLK_SYS_AARCH64_NEON
1414
#include "aarch64/meta.h"
1515
#endif
1616

mlkem/src/sys.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,21 @@
3737
#define MLK_SYS_AARCH64
3838
#endif
3939

40+
/* Check if the AArch64 compilation target supports NEON (Advanced SIMD).
41+
*
42+
* Some compilers also define __ARM_NEON__, but __ARM_NEON is the most reliable
43+
* signal. Specifically, clang on Apple appears to keep __ARM_NEON__ set even if
44+
* -march=armv8-a+nosimd is set.
45+
*
46+
* gcc 4.8 -- the first gcc version introducing Neon support -- sets neither
47+
* __ARM_NEON nor __ARM_NEON__; in fact, there is no preprocessor signal that
48+
* Neon is enabled. If you use gcc 4.8, you should set __ARM_NEON manually.
49+
* gcc 4.9 onwards do set __ARM_NEON.
50+
*/
51+
#if defined(MLK_SYS_AARCH64) && defined(__ARM_NEON)
52+
#define MLK_SYS_AARCH64_NEON
53+
#endif
54+
4055
/* Check if we're running on an AArch64 big endian system. */
4156
#if defined(__AARCH64EB__)
4257
#define MLK_SYS_AARCH64_EB

scripts/autogen

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4620,10 +4620,10 @@ ABI_CAPS = {
46204620
},
46214621
"NEON": {
46224622
"asm_subdir": "aarch64",
4623-
"guard": None,
4623+
"guard": "MLK_SYS_AARCH64_NEON",
46244624
"syscap": "MLK_SYS_CAP_NEON",
46254625
"description": "AArch64 NEON",
4626-
"cflags": [],
4626+
"cflags": ["-march=armv8-a+simd"],
46274627
"aux_files": [],
46284628
},
46294629
"SHA3": {

test/abicheck/aarch64/abicheck_aarch64.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ int check_aarch64_aapcs_compliance(struct aarch64_register_state *before,
4444
}
4545
}
4646

47-
/* The call stub leaves vector output untouched when NEON is unavailable. */
47+
/* The call stub leaves vector output untouched when NEON was not compiled
48+
* in or is unavailable at runtime. */
49+
#if defined(MLK_SYS_AARCH64_NEON)
4850
if (mlk_sys_check_capability(MLK_SYS_CAP_NEON))
4951
{
5052
/* Check callee-saved NEON registers (d8-d15, lower 64 bits only). */
@@ -57,6 +59,7 @@ int check_aarch64_aapcs_compliance(struct aarch64_register_state *before,
5759
}
5860
}
5961
}
62+
#endif /* MLK_SYS_AARCH64_NEON */
6063

6164
return violations;
6265
}

test/abicheck/aarch64/abicheck_aarch64.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ static MLK_INLINE void call_stub_aarch64(struct aarch64_register_state *input,
3232
struct aarch64_register_state *output,
3333
void (*function_ptr)(void))
3434
{
35+
#if defined(MLK_SYS_AARCH64_NEON)
3536
int use_neon = mlk_sys_check_capability(MLK_SYS_CAP_NEON) != 0;
37+
#else
38+
int use_neon = 0;
39+
#endif
3640
asm_call_stub_aarch64(input, output, function_ptr, use_neon);
3741
}
3842

0 commit comments

Comments
 (0)