[llvm] [Support/BLAKE3] Make g_cpu_features thread safe (PR #147948)
Dmitry Vasilyev via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 10 05:02:28 PDT 2025
https://github.com/slydiman created https://github.com/llvm/llvm-project/pull/147948
`g_cpu_features` can be updated multiple times by `get_cpu_features()`, which reports a thread sanitizer error when used with multiple lld threads.
>From ba1c486467dd3a0ee9d53a60bb84631a79b39fe8 Mon Sep 17 00:00:00 2001
From: Dmitry Vassiliev <dvassiliev at accesssoftek.com>
Date: Fri, 27 Jun 2025 14:34:52 +0400
Subject: [PATCH] [Support/BLAKE3] Make g_cpu_features thread safe
`g_cpu_features` can be updated multiple times by `get_cpu_features()`, which reports a thread sanitizer error when used with multiple lld threads.
---
llvm/lib/Support/BLAKE3/blake3_dispatch.c | 42 ++++++++++++++++++++---
1 file changed, 37 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Support/BLAKE3/blake3_dispatch.c b/llvm/lib/Support/BLAKE3/blake3_dispatch.c
index e96e714225f41..6c156f123dd5b 100644
--- a/llvm/lib/Support/BLAKE3/blake3_dispatch.c
+++ b/llvm/lib/Support/BLAKE3/blake3_dispatch.c
@@ -14,6 +14,36 @@
#endif
#endif
+/* Atomic access abstraction (since MSVC does not do C11 yet) */
+#if defined(_MSC_VER) && !defined(__clang__)
+#if !defined(IS_X86)
+#include <intrin.h>
+#endif
+#pragma warning(disable : 5105)
+#ifndef FORCEINLINE
+#define FORCEINLINE inline __forceinline
+#endif
+typedef volatile long atomic32_t;
+static FORCEINLINE int32_t atomic_load32(atomic32_t *src) {
+ return _InterlockedOr(src, 0);
+}
+static FORCEINLINE void atomic_store32(atomic32_t *dst, int32_t val) {
+ _InterlockedExchange(dst, val);
+}
+#else
+#include <stdatomic.h>
+#ifndef FORCEINLINE
+#define FORCEINLINE inline __attribute__((__always_inline__))
+#endif
+typedef volatile _Atomic(int32_t) atomic32_t;
+static FORCEINLINE int32_t atomic_load32(atomic32_t *src) {
+ return atomic_load_explicit(src, memory_order_relaxed);
+}
+static FORCEINLINE void atomic_store32(atomic32_t *dst, int32_t val) {
+ atomic_store_explicit(dst, val, memory_order_relaxed);
+}
+#endif
+
#define MAYBE_UNUSED(x) (void)((x))
#if defined(IS_X86)
@@ -76,7 +106,7 @@ enum cpu_feature {
#if !defined(BLAKE3_TESTING)
static /* Allow the variable to be controlled manually for testing */
#endif
- enum cpu_feature g_cpu_features = UNDEFINED;
+ atomic32_t g_cpu_features = UNDEFINED;
LLVM_ATTRIBUTE_USED
#if !defined(BLAKE3_TESTING)
@@ -84,9 +114,10 @@ static
#endif
enum cpu_feature
get_cpu_features(void) {
-
- if (g_cpu_features != UNDEFINED) {
- return g_cpu_features;
+ enum cpu_feature _cpu_features;
+ _cpu_features = (enum cpu_feature)atomic_load32(&g_cpu_features);
+ if (_cpu_features != UNDEFINED) {
+ return _cpu_features;
} else {
#if defined(IS_X86)
uint32_t regs[4] = {0};
@@ -125,10 +156,11 @@ static
}
}
}
- g_cpu_features = features;
+ atomic_store32(&g_cpu_features, (int32_t)features);
return features;
#else
/* How to detect NEON? */
+ atomic_store32(&g_cpu_features, 0);
return 0;
#endif
}
More information about the llvm-commits
mailing list