Skip to content

Commit 0da6528

Browse files
committed
Merge branch 'blake3-make-sanitizer-happy' of https://github.com/slydiman/llvm-project into blake3-make-sanitizer-happy
2 parents 535d691 + 454f20d commit 0da6528

File tree

1 file changed

+40
-8
lines changed

1 file changed

+40
-8
lines changed

llvm/lib/Support/BLAKE3/blake3_dispatch.c

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,46 @@
44

55
#include "blake3_impl.h"
66

7+
#if defined(_MSC_VER)
8+
#include <Windows.h>
9+
#endif
10+
711
#if defined(IS_X86)
812
#if defined(_MSC_VER)
913
#include <intrin.h>
1014
#elif defined(__GNUC__)
1115
#include <immintrin.h>
1216
#else
13-
#error "Unimplemented!"
17+
#undef IS_X86 /* Unimplemented! */
1418
#endif
1519
#endif
1620

21+
#if !defined(BLAKE3_ATOMICS)
22+
#if defined(__has_include)
23+
#if __has_include(<stdatomic.h>) && !defined(_MSC_VER)
24+
#define BLAKE3_ATOMICS 1
25+
#else
26+
#define BLAKE3_ATOMICS 0
27+
#endif /* __has_include(<stdatomic.h>) && !defined(_MSC_VER) */
28+
#else
29+
#define BLAKE3_ATOMICS 0
30+
#endif /* defined(__has_include) */
31+
#endif /* BLAKE3_ATOMICS */
32+
33+
#if BLAKE3_ATOMICS
34+
#define ATOMIC_INT _Atomic int
35+
#define ATOMIC_LOAD(x) x
36+
#define ATOMIC_STORE(x, y) x = y
37+
#elif defined(_MSC_VER)
38+
#define ATOMIC_INT LONG
39+
#define ATOMIC_LOAD(x) InterlockedOr(&x, 0)
40+
#define ATOMIC_STORE(x, y) InterlockedExchange(&x, y)
41+
#else
42+
#define ATOMIC_INT int
43+
#define ATOMIC_LOAD(x) x
44+
#define ATOMIC_STORE(x, y) x = y
45+
#endif
46+
1747
#define MAYBE_UNUSED(x) (void)((x))
1848

1949
#if defined(IS_X86)
@@ -59,7 +89,6 @@ static void cpuidex(uint32_t out[4], uint32_t id, uint32_t sid) {
5989
#endif
6090
}
6191

62-
#endif
6392

6493
enum cpu_feature {
6594
SSE2 = 1 << 0,
@@ -76,7 +105,7 @@ enum cpu_feature {
76105
#if !defined(BLAKE3_TESTING)
77106
static /* Allow the variable to be controlled manually for testing */
78107
#endif
79-
enum cpu_feature g_cpu_features = UNDEFINED;
108+
ATOMIC_INT g_cpu_features = UNDEFINED;
80109

81110
LLVM_ATTRIBUTE_USED
82111
#if !defined(BLAKE3_TESTING)
@@ -85,14 +114,16 @@ static
85114
enum cpu_feature
86115
get_cpu_features(void) {
87116

88-
if (g_cpu_features != UNDEFINED) {
89-
return g_cpu_features;
117+
/* If TSAN detects a data race here, try compiling with -DBLAKE3_ATOMICS=1 */
118+
enum cpu_feature features = ATOMIC_LOAD(g_cpu_features);
119+
if (features != UNDEFINED) {
120+
return features;
90121
} else {
91122
#if defined(IS_X86)
92123
uint32_t regs[4] = {0};
93124
uint32_t *eax = &regs[0], *ebx = &regs[1], *ecx = &regs[2], *edx = &regs[3];
94125
(void)edx;
95-
enum cpu_feature features = 0;
126+
features = 0;
96127
cpuid(regs, 0);
97128
const int max_id = *eax;
98129
cpuid(regs, 1);
@@ -102,7 +133,7 @@ static
102133
if (*edx & (1UL << 26))
103134
features |= SSE2;
104135
#endif
105-
if (*ecx & (1UL << 0))
136+
if (*ecx & (1UL << 9))
106137
features |= SSSE3;
107138
if (*ecx & (1UL << 19))
108139
features |= SSE41;
@@ -125,14 +156,15 @@ static
125156
}
126157
}
127158
}
128-
g_cpu_features = features;
159+
ATOMIC_STORE(g_cpu_features, features);
129160
return features;
130161
#else
131162
/* How to detect NEON? */
132163
return 0;
133164
#endif
134165
}
135166
}
167+
#endif
136168

137169
void blake3_compress_in_place(uint32_t cv[8],
138170
const uint8_t block[BLAKE3_BLOCK_LEN],

0 commit comments

Comments
 (0)