On 12/07/2026 00:06, Dominic P wrote:
The Arm C Language Extensions require a conforming implementation to
predefine __ARM_ACLE (ACLE, "Testing for Arm C Language Extensions").
GCC has never defined it on either Arm port, so portable code following
the ACLE recommendation of guarding #include <arm_acle.h> (and intrinsic
use such as __crc32b with -march=armv8-a+crc) on __ARM_ACLE never saw
the intrinsics.  PR70974 itself was reported against an AArch64 (HiKey,
-march=armv8-a+crc) configuration, so define the macro on both ports:
on arm in arm_cpu_builtins, on aarch64 beside the other unconditional
ACLE macros in aarch64_define_unconditional_macros.

The gap has real-world fallout: Ceph's cmake CRC/crypto detection had to
stop trusting __ARM_ACLE to signal arm_acle.h availability (Ceph tracker
issue 19386, which cites this PR), and Crypto++ hit the same failure
(weidai11/cryptopp issue 238).

ACLE historically encodes this macro as 100 * major + minor, so ACLE 2.0
is 200.  Define __ARM_ACLE to 200 unconditionally on both ports.  200 is
the value clang predefines on its 32-bit Arm target, and reflects the
ACLE 2.0-level intrinsic surface the ports provide.  (Newer ACLE
releases switched to a date-based encoding -- clang's AArch64 target now
predefines 202420 -- but GCC's intrinsic surface has not tracked those
quarterly additions, so 200 remains the accurate conformance level and
avoids over-claiming; the two GCC ports intentionally agree on one
value.)

Hi Dominic,
you are correctly pointing out that ACLE moved this value to a date based implementation [1]. Since then we have moved to a live-at-HEAD model where the main branch of the ACLE repository is the current specification [2]. This means that the concept of ACLE releases has been deprecated.
We are debating the value __ARM_ACLE should have in [3].

To give more context, given that different compiler implementations have different alignment, the only reasonable thing one can do with __ARM_ACLE is test whether the compiler supports the Arm C Language Extensions, full stop. Trying to decide whether a feature is present based on its value is not going to work.

Use of specific intrinsics should be enabled after checking that their relative FEAT defines are available, like __ARM_FEATURE_SVE2p3. And for some of them, users should do some runtime checks [4] to ensure specific hardware support is enabled. Look for "Use of this intrinsic if `svcntb() * 8 < 256` results in undefined behaviour" in the current acle.md file [4].

Redmine, now that brings back memories! I had a look at https://tracker.ceph.com/issues/19386 and am convinced these should use something like __ARM_FEATURE_CRC32, __ARM_FEATURE_CRYPTO and more recently __ARM_FEATURE_SHA2, __ARM_FEATURE_AES and similar.

Hope this helps,
Claudio

[1] https://github.com/ARM-software/acle/pull/294
[2] https://github.com/ARM-software/acle/pull/448
[3] https://github.com/ARM-software/acle/pull/441
[4] https://github.com/ARM-software/acle/blob/main/main/acle.md


gcc/ChangeLog:

        PR target/70974
        * config/arm/arm-c.cc (arm_cpu_builtins): Define __ARM_ACLE to
        200.
        * config/aarch64/aarch64-c.cc
        (aarch64_define_unconditional_macros): Likewise.

gcc/testsuite/ChangeLog:

        PR target/70974
        * gcc.target/arm/acle/pr70974.c: New test.
        * gcc.target/aarch64/acle/pr70974.c: New test.

Signed-off-by: Dominic P <[email protected]>
---
  gcc/config/aarch64/aarch64-c.cc               |  4 ++++
  gcc/config/arm/arm-c.cc                       |  4 ++++
  .../gcc.target/aarch64/acle/pr70974.c         | 21 +++++++++++++++++++
  gcc/testsuite/gcc.target/arm/acle/pr70974.c   | 20 ++++++++++++++++++
  4 files changed, 49 insertions(+)
  create mode 100644 gcc/testsuite/gcc.target/aarch64/acle/pr70974.c
  create mode 100644 gcc/testsuite/gcc.target/arm/acle/pr70974.c

diff --git a/gcc/config/aarch64/aarch64-c.cc b/gcc/config/aarch64/aarch64-c.cc
index e11cf95a0..eaff140fd 100644
--- a/gcc/config/aarch64/aarch64-c.cc
+++ b/gcc/config/aarch64/aarch64-c.cc
@@ -59,6 +59,10 @@ aarch64_define_unconditional_macros (cpp_reader *pfile)
    builtin_define ("__aarch64__");
    builtin_define ("__ARM_64BIT_STATE");
+ /* Per the ACLE the value of __ARM_ACLE is 100 * major_version
+     + minor_version.  GCC implements ACLE 2.0.  */
+  builtin_define_with_int_value ("__ARM_ACLE", 200);
+
    builtin_define ("__ARM_ARCH_ISA_A64");
    builtin_define_with_int_value ("__ARM_ALIGN_MAX_PWR", 28);
    builtin_define_with_int_value ("__ARM_ALIGN_MAX_STACK_PWR", 16);
diff --git a/gcc/config/arm/arm-c.cc b/gcc/config/arm/arm-c.cc
index 65002481c..aaf75038e 100644
--- a/gcc/config/arm/arm-c.cc
+++ b/gcc/config/arm/arm-c.cc
@@ -222,6 +222,10 @@ def_or_undef_macro(struct cpp_reader* pfile, const char 
*name, bool def_p)
  static void
  arm_cpu_builtins (struct cpp_reader* pfile)
  {
+  /* Per the ACLE the value of __ARM_ACLE is 100 * major_version
+     + minor_version.  GCC implements ACLE 2.0.  */
+  builtin_define_with_int_value ("__ARM_ACLE", 200);
+
    def_or_undef_macro (pfile, "__ARM_FEATURE_DSP", TARGET_DSP_MULTIPLY);
    def_or_undef_macro (pfile, "__ARM_FEATURE_QBIT", TARGET_ARM_QBIT);
    def_or_undef_macro (pfile, "__ARM_FEATURE_SAT", TARGET_ARM_SAT);
diff --git a/gcc/testsuite/gcc.target/aarch64/acle/pr70974.c 
b/gcc/testsuite/gcc.target/aarch64/acle/pr70974.c
new file mode 100644
index 000000000..b072508ad
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/acle/pr70974.c
@@ -0,0 +1,21 @@
+/* PR target/70974.  Check that the __ARM_ACLE predefined macro announces
+   the ACLE version implemented, so that code following the ACLE
+   recommendations can decide to include arm_acle.h.  The PR was reported
+   against an AArch64 configuration.  */
+/* { dg-do compile } */
+
+#ifndef __ARM_ACLE
+#error "__ARM_ACLE is not defined"
+#endif
+
+#if __ARM_ACLE < 200
+#error "__ARM_ACLE is less than 200"
+#endif
+
+#include "arm_acle.h"
+
+int
+main (void)
+{
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/arm/acle/pr70974.c 
b/gcc/testsuite/gcc.target/arm/acle/pr70974.c
new file mode 100644
index 000000000..39058eef2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/pr70974.c
@@ -0,0 +1,20 @@
+/* PR target/70974.  Check that the __ARM_ACLE predefined macro announces
+   the ACLE version implemented, so that code following the ACLE
+   recommendations can decide to include arm_acle.h.  */
+/* { dg-do compile } */
+
+#ifndef __ARM_ACLE
+#error "__ARM_ACLE is not defined"
+#endif
+
+#if __ARM_ACLE < 200
+#error "__ARM_ACLE is less than 200"
+#endif
+
+#include "arm_acle.h"
+
+int
+main (void)
+{
+  return 0;
+}

Reply via email to