[compiler-rt] [scudo] Add support for LoongArch hardware CRC32 checksumming (PR #83113)

WÁNG Xuěruì via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 27 00:44:18 PST 2024


https://github.com/xen0n created https://github.com/llvm/llvm-project/pull/83113

The support is available for processors implementing the LoongArch64 subset, but one still has to probe for platform capability prior to use, according to LoongArch documentation.

>From 630b3aafd580326ffb5d3daee261fcc2d8177263 Mon Sep 17 00:00:00 2001
From: WANG Xuerui <git at xen0n.name>
Date: Tue, 27 Feb 2024 16:20:46 +0800
Subject: [PATCH] [scudo] Add support for LoongArch hardware CRC32 checksumming

The support is available for processors implementing the LoongArch64
subset, but one still has to probe for platform capability prior to use,
according to LoongArch documentation.
---
 compiler-rt/lib/scudo/standalone/checksum.cpp | 10 ++++++++++
 compiler-rt/lib/scudo/standalone/checksum.h   |  4 ++++
 compiler-rt/lib/scudo/standalone/crc32_hw.cpp |  7 +++++++
 3 files changed, 21 insertions(+)

diff --git a/compiler-rt/lib/scudo/standalone/checksum.cpp b/compiler-rt/lib/scudo/standalone/checksum.cpp
index 2c277391a2ec16..09fa5417653a7a 100644
--- a/compiler-rt/lib/scudo/standalone/checksum.cpp
+++ b/compiler-rt/lib/scudo/standalone/checksum.cpp
@@ -19,6 +19,8 @@
 #else
 #include <sys/auxv.h>
 #endif
+#elif defined(__loongarch_lp64)
+#include <sys/auxv.h>
 #endif
 
 namespace scudo {
@@ -75,6 +77,14 @@ bool hasHardwareCRC32() {
   return !!(getauxval(AT_HWCAP) & HWCAP_CRC32);
 #endif // SCUDO_FUCHSIA
 }
+#elif defined(__loongarch_lp64)
+// Query HWCAP for platform capability, according to *Software Development and
+// Build Convention for LoongArch Architectures* v0.1, Section 9.1.
+//
+// Link: https://github.com/loongson/la-softdev-convention/blob/v0.1/la-softdev-convention.adoc#kernel-development
+bool hasHardwareCRC32() {
+  return !!(getauxval(AT_HWCAP) & HWCAP_LOONGARCH_CRC32);
+}
 #else
 // No hardware CRC32 implemented in Scudo for other architectures.
 bool hasHardwareCRC32() { return false; }
diff --git a/compiler-rt/lib/scudo/standalone/checksum.h b/compiler-rt/lib/scudo/standalone/checksum.h
index f8eda81fd91288..b5f97fe5111f04 100644
--- a/compiler-rt/lib/scudo/standalone/checksum.h
+++ b/compiler-rt/lib/scudo/standalone/checksum.h
@@ -30,6 +30,10 @@
 #include <arm_acle.h>
 #define CRC32_INTRINSIC FIRST_32_SECOND_64(__crc32cw, __crc32cd)
 #endif
+#ifdef __loongarch_lp64
+#include <larchintrin.h>
+#define CRC32_INTRINSIC FIRST_32_SECOND_64(__crcc_w_w_w, __crcc_w_d_w)
+#endif
 
 namespace scudo {
 
diff --git a/compiler-rt/lib/scudo/standalone/crc32_hw.cpp b/compiler-rt/lib/scudo/standalone/crc32_hw.cpp
index 73f2ae000c63d6..3f8c423fa0f49e 100644
--- a/compiler-rt/lib/scudo/standalone/crc32_hw.cpp
+++ b/compiler-rt/lib/scudo/standalone/crc32_hw.cpp
@@ -17,4 +17,11 @@ u32 computeHardwareCRC32(u32 Crc, uptr Data) {
 #endif // defined(__CRC32__) || defined(__SSE4_2__) ||
        // defined(__ARM_FEATURE_CRC32)
 
+#if defined(__loongarch_lp64)
+u32 computeHardwareCRC32(u32 Crc, uptr Data) {
+  // The LoongArch CRC intrinsics have the two input arguments swapped.
+  return static_cast<u32>(CRC32_INTRINSIC(Data, Crc));
+}
+#endif // defined(__loongarch_lp64)
+
 } // namespace scudo



More information about the llvm-commits mailing list