https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93370
Bug ID: 93370 Summary: Aarch64 accepts but ignores target("+sm4") unless ARMv8.2-A is enabled Product: gcc Version: 9.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: lloyd at randombit dot net Target Milestone: --- Aarch64 8.2-A has an optional extension for SM4. This is a Chinese cryptographic algorithm analogous to AES. GCC supports these via intrinsic. The confusion came about because GCC accepts `__attribute__((target("+sm4")))` but unless ARMv8.2-A is also enabled (eg via -march=armv8.2-a command line flag) then it complains about a target specific option mismatch, which is the usual error when trying to use an intrinsic for an extension that is not enabled when compiling that function or file. In contrast if you pass something GCC doesn't know about to target() then it errors with a clear message "pragma or attribute 'target("+foo")' is not valid". Example: $ aarch64-linux-gnu-gcc -v Using built-in specs. COLLECT_GCC=aarch64-linux-gnu-gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/aarch64-linux-gnu/9.2.0/lto-wrapper Target: aarch64-linux-gnu Configured with: /build/aarch64-linux-gnu-gcc/src/gcc-9.2.0/configure --prefix=/usr --program-prefix=aarch64-linux-gnu- --with-local-prefix=/usr/aarch64-linux-gnu --with-sysroot=/usr/aarch64-linux-gnu --with-build-sysroot=/usr/aarch64-linux-gnu --with-native-system-header-dir=/include --libdir=/usr/lib --libexecdir=/usr/lib --target=aarch64-linux-gnu --host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --disable-nls --enable-languages=c,c++,fortran --enable-shared --enable-threads=posix --with-system-zlib --with-isl --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-gnu-unique-object --enable-linker-build-id --enable-lto --enable-plugin --enable-install-libiberty --with-linker-hash-style=gnu --enable-gnu-indirect-function --disable-multilib --disable-werror --enable-checking=release Thread model: posix gcc version 9.2.0 (GCC) $ cat sm4.c #include <arm_neon.h> #if WORKS #define TARGET "arch=armv8.2-a+sm4" #else #define TARGET "+sm4" #endif void __attribute__((target(TARGET))) enc(uint32_t b[4]) { uint32x4_t B = vld1q_u32(b); vsm4eq_u32(B, B); // from SM4 extension vst1q_u32(b, B); } $ aarch64-linux-gnu-gcc -DWORKS=1 -Wall -Wextra -c sm4.c -o sm4.o $ aarch64-linux-gnu-gcc -DWORKS=0 -march=armv8.2-a -Wall -Wextra -c sm4.c -o sm4.o $ aarch64-linux-gnu-gcc -DWORKS=0 -Wall -Wextra -c sm4.c -o sm4.o In file included from sm4.c:1: /usr/lib/gcc/aarch64-linux-gnu/9.2.0/include/arm_neon.h: In function 'void enc(uint32_t*)': /usr/lib/gcc/aarch64-linux-gnu/9.2.0/include/arm_neon.h:33125:1: error: inlining failed in call to always_inline 'uint32x4_t vsm4eq_u32(uint32x4_t, uint32x4_t)': target specific option mismatch 33125 | vsm4eq_u32 (uint32x4_t __a, uint32x4_t __b) | ^~~~~~~~~~ sm4.c:12:14: note: called from here 12 | vsm4eq_u32(B, B); | ~~~~~~~~~~^~~~~~ In file included from sm4.c:1: /usr/lib/gcc/aarch64-linux-gnu/9.2.0/include/arm_neon.h:33125:1: error: inlining failed in call to always_inline 'uint32x4_t vsm4eq_u32(uint32x4_t, uint32x4_t)': target specific option mismatch 33125 | vsm4eq_u32 (uint32x4_t __a, uint32x4_t __b) | ^~~~~~~~~~ sm4.c:12:14: note: called from here 12 | vsm4eq_u32(B, B); | ~~~~~~~~~~^~~~~~ This is not a huge bug but it would be nice if GCC gave a more obvious error to hint at the problem, since it accepts +sm4 but does not actually respect it unless ARMv8.2-A is separately enabled. I imagine this situation holds true for some of the other Aarch64 extensions but have not checked this.