[zlib] Tweak optimizations to work better with ThinLTO
ThinLTO emits warnings when linking modules with different target
triples. Android uses armv7-a as its default triple, so the mixing with
armv8-a here is problematic.
Bug: 807147
Test: md5sum <(objdump -d crc32_simd.o) is the same for Android.
Change-Id: If2bffc4090d3d94f158eea80d19ee9eb827fc837
Reviewed-on: https://chromium-review.googlesource.com/1147867
Commit-Queue: George Burgess <gbiv@chromium.org>
Reviewed-by: Mike Klein <mtklein@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#585338}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 708d7d6be05885487cb5ccdffeab08a09ab1ea60
diff --git a/BUILD.gn b/BUILD.gn
index 69b49ba..b44bda6 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -78,7 +78,7 @@
source_set("zlib_arm_crc32") {
visibility = [ ":*" ]
- if (!is_ios && !is_chromeos && !is_fuchsia) {
+ if (is_clang && (!is_ios && !is_chromeos && !is_fuchsia)) {
include_dirs = [ "." ]
if (is_android) {
@@ -97,10 +97,6 @@
"crc32_simd.h",
]
- if (!is_win || is_clang) {
- cflags_c = [ "-march=armv8-a+crc" ]
- }
-
if (!is_debug) {
configs -= [ "//build/config/compiler:default_optimization" ]
configs += [ "//build/config/compiler:optimize_speed" ]
diff --git a/crc32_simd.c b/crc32_simd.c
index c20b8eb..03698ad 100644
--- a/crc32_simd.c
+++ b/crc32_simd.c
@@ -160,8 +160,34 @@
*
* TODO: implement a version using the PMULL instruction.
*/
-#include <arm_acle.h>
+/* 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
+ * warn, and Android defaults to armv7-a. This restriction does not apply to
+ * function-level `target`s, however.)
+ *
+ * Since we only need three crc intrinsics, and since clang's implementation of
+ * those are just wrappers around compiler builtins, it's simplest to #define
+ * those builtins directly. If this #define list grows too much (or we depend on
+ * an intrinsic that isn't a trivial wrapper), we may have to find a better way
+ * to go about this.
+ *
+ * NOTE: clang currently complains that "'+soft-float-abi' is not a recognized
+ * feature for this target (ignoring feature)." This appears to be a harmless
+ * bug in clang.
+ */
+#define __crc32b __builtin_arm_crc32b
+#define __crc32d __builtin_arm_crc32d
+#define __crc32w __builtin_arm_crc32w
+
+#if defined(__aarch64__)
+#define TARGET_ARMV8_WITH_CRC __attribute__((target("crc")))
+#else
+#define TARGET_ARMV8_WITH_CRC __attribute__((target("armv8-a,crc")))
+#endif
+
+TARGET_ARMV8_WITH_CRC
uint32_t ZLIB_INTERNAL armv8_crc32_little(unsigned long crc,
const unsigned char *buf,
z_size_t len)
@@ -202,6 +228,7 @@
return ~c;
}
+TARGET_ARMV8_WITH_CRC
Pos ZLIB_INTERNAL insert_string_arm(deflate_state *const s, const Pos str)
{
Pos ret;