zlib: fix ARMv8 CRC32 compilation in GCC
GCC compilation in ARM architectures with CRC32 extension was
broken, as the extension was guarded for clang.
For GCC we are enforcing armv8-a+crc architecture at module
level, so the builtin extensions are available. Then we
just include arm_acle.h to declare the required builtins.
ThinLTO requires all modules to use same target, so this
change makes GCC fail with ThinLTO (that was not supported
anyway). Added a GN assert to explicitely fail in this case.
Adapted from Vladislav Mukulov <vladislav.mukulov@lge.com>
original patch.
Bug: 819294
Change-Id: Ifa5cf64318f88220052c44126db90bef999b7113
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1642730
Reviewed-by: Adenilson Cavalcanti <cavalcantii@chromium.org>
Commit-Queue: José Dapena Paz <jose.dapena@lge.com>
Cr-Original-Commit-Position: refs/heads/master@{#667541}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 68e95088b6f73f489aa1e1023b7864794627cae1
diff --git a/BUILD.gn b/BUILD.gn
index 1a9cd3b..3b8e5e9 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -89,7 +89,7 @@
source_set("zlib_arm_crc32") {
visibility = [ ":*" ]
- if (is_clang && !is_ios) {
+ if (!is_ios) {
include_dirs = [ "." ]
if (is_android) {
@@ -101,6 +101,10 @@
} else {
assert(false, "CPU detection requires the Android NDK")
}
+ } else if (!is_win && !is_clang) {
+ assert(!thin_lto_enable_optimizations,
+ "ThinLTO fails mixing different module-level targets")
+ cflags_c = [ "-march=armv8-a+crc" ]
}
sources = [
diff --git a/crc32_simd.c b/crc32_simd.c
index 03698ad..2fef610 100644
--- a/crc32_simd.c
+++ b/crc32_simd.c
@@ -161,6 +161,7 @@
* TODO: implement a version using the PMULL instruction.
*/
+#if defined(__clang__)
/* CRC32 intrinsics are #ifdef'ed out of arm_acle.h unless we build with an
* armv8 target, which is incompatible with ThinLTO optimizations on Android.
* (Namely, mixing and matching different module-level targets makes ThinLTO
@@ -183,8 +184,18 @@
#if defined(__aarch64__)
#define TARGET_ARMV8_WITH_CRC __attribute__((target("crc")))
-#else
+#else // !defined(__aarch64__)
#define TARGET_ARMV8_WITH_CRC __attribute__((target("armv8-a,crc")))
+#endif // defined(__aarch64__)
+
+#elif defined(__GNUC__)
+/* For GCC, we are setting CRC extensions at module level, so ThinLTO is not
+ * allowed. We can just include arm_acle.h.
+ */
+#include <arm_acle.h>
+#define TARGET_ARMV8_WITH_CRC
+#else // !defined(__GNUC__) && !defined(_aarch64__)
+#error ARM CRC32 SIMD extensions only supported for Clang and GCC
#endif
TARGET_ARMV8_WITH_CRC
@@ -248,5 +259,4 @@
return ret;
}
-
#endif