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.)

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;
+}
-- 
2.55.0

Reply via email to