[compiler-rt] [tsan][go]: add a128 store, load, compare_exchange (PR #196833)
Mauri de Souza Meneguzzo via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 16 06:29:41 PDT 2026
https://github.com/mauri870 updated https://github.com/llvm/llvm-project/pull/196833
>From a80da2a8c7bc0e2ffa60a135014fe52f38c574c0 Mon Sep 17 00:00:00 2001
From: Mauri de Souza Meneguzzo <mauri870 at gmail.com>
Date: Sat, 9 May 2026 20:34:03 -0300
Subject: [PATCH] [tsan][go]: add a128 load, store, compare_exchange
---
compiler-rt/lib/tsan/rtl/tsan_interface.h | 16 +++++++--
.../lib/tsan/rtl/tsan_interface_atomic.cpp | 34 ++++++++++++++++---
2 files changed, 43 insertions(+), 7 deletions(-)
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interface.h b/compiler-rt/lib/tsan/rtl/tsan_interface.h
index db94cf48f9c2d..1e2c4b36284e4 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interface.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_interface.h
@@ -207,8 +207,7 @@ typedef unsigned char a8;
typedef unsigned short a16;
typedef unsigned int a32;
typedef unsigned long long a64;
-#if !SANITIZER_GO && \
- (defined(__SIZEOF_INT128__) || \
+#if (defined(__SIZEOF_INT128__) || \
(__clang_major__ * 100 + __clang_minor__ >= 302)) && \
!defined(__mips64) && !defined(__s390x__)
__extension__ typedef __int128 a128;
@@ -411,10 +410,18 @@ SANITIZER_INTERFACE_ATTRIBUTE
void __tsan_go_atomic32_load(ThreadState *thr, uptr cpc, uptr pc, u8 *a);
SANITIZER_INTERFACE_ATTRIBUTE
void __tsan_go_atomic64_load(ThreadState *thr, uptr cpc, uptr pc, u8 *a);
+#if __TSAN_HAS_INT128
+SANITIZER_INTERFACE_ATTRIBUTE
+void __tsan_go_atomic128_load(ThreadState* thr, uptr cpc, uptr pc, u8* a);
+#endif
SANITIZER_INTERFACE_ATTRIBUTE
void __tsan_go_atomic32_store(ThreadState *thr, uptr cpc, uptr pc, u8 *a);
SANITIZER_INTERFACE_ATTRIBUTE
void __tsan_go_atomic64_store(ThreadState *thr, uptr cpc, uptr pc, u8 *a);
+#if __TSAN_HAS_INT128
+SANITIZER_INTERFACE_ATTRIBUTE
+void __tsan_go_atomic128_store(ThreadState* thr, uptr cpc, uptr pc, u8* a);
+#endif
SANITIZER_INTERFACE_ATTRIBUTE
void __tsan_go_atomic32_fetch_add(ThreadState *thr, uptr cpc, uptr pc, u8 *a);
SANITIZER_INTERFACE_ATTRIBUTE
@@ -437,6 +444,11 @@ void __tsan_go_atomic32_compare_exchange(ThreadState *thr, uptr cpc, uptr pc,
SANITIZER_INTERFACE_ATTRIBUTE
void __tsan_go_atomic64_compare_exchange(ThreadState *thr, uptr cpc, uptr pc,
u8 *a);
+#if __TSAN_HAS_INT128
+SANITIZER_INTERFACE_ATTRIBUTE
+void __tsan_go_atomic128_compare_exchange(ThreadState* thr, uptr cpc, uptr pc,
+ u8* a);
+#endif
} // extern "C"
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interface_atomic.cpp b/compiler-rt/lib/tsan/rtl/tsan_interface_atomic.cpp
index 5c2461634d2d4..5dd86e05c96b9 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interface_atomic.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_interface_atomic.cpp
@@ -28,7 +28,7 @@
using namespace __tsan;
-#if !SANITIZER_GO && __TSAN_HAS_INT128
+#if __TSAN_HAS_INT128
// Protects emulation of 128-bit atomic operations.
static StaticSpinMutex mutex128;
#endif
@@ -112,8 +112,7 @@ T func_cas(volatile T *v, T cmp, T xch) {
// Atomic ops are executed under tsan internal mutex,
// here we assume that the atomic variables are not accessed
// from non-instrumented code.
-#if !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) && !SANITIZER_GO && \
- __TSAN_HAS_INT128
+#if !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) && __TSAN_HAS_INT128
a128 func_xchg(volatile a128 *v, a128 op) {
SpinMutexLock lock(&mutex128);
a128 cmp = *v;
@@ -253,7 +252,7 @@ struct OpLoad {
return atomic_load(to_atomic(a), to_mo(mo));
}
-#if __TSAN_HAS_INT128 && !SANITIZER_GO
+#if __TSAN_HAS_INT128
static a128 NoTsanAtomic(morder mo, const volatile a128 *a) {
SpinMutexLock lock(&mutex128);
return *a;
@@ -294,7 +293,7 @@ struct OpStore {
atomic_store(to_atomic(a), v, to_mo(mo));
}
-#if __TSAN_HAS_INT128 && !SANITIZER_GO
+#if __TSAN_HAS_INT128
static void NoTsanAtomic(morder mo, volatile a128 *a, a128 v) {
SpinMutexLock lock(&mutex128);
*a = v;
@@ -928,6 +927,13 @@ void __tsan_go_atomic64_load(ThreadState *thr, uptr cpc, uptr pc, u8 *a) {
*(a64 *)(a + 8) = AtomicGoRet<OpLoad>(thr, cpc, pc, mo_acquire, *(a64 **)a);
}
+# if __TSAN_HAS_INT128
+SANITIZER_INTERFACE_ATTRIBUTE
+void __tsan_go_atomic128_load(ThreadState* thr, uptr cpc, uptr pc, u8* a) {
+ *(a128*)(a + 8) = AtomicGoRet<OpLoad>(thr, cpc, pc, mo_acquire, *(a128**)a);
+}
+# endif
+
SANITIZER_INTERFACE_ATTRIBUTE
void __tsan_go_atomic32_store(ThreadState *thr, uptr cpc, uptr pc, u8 *a) {
AtomicGo<OpStore>(thr, cpc, pc, mo_release, *(a32 **)a, *(a32 *)(a + 8));
@@ -938,6 +944,13 @@ void __tsan_go_atomic64_store(ThreadState *thr, uptr cpc, uptr pc, u8 *a) {
AtomicGo<OpStore>(thr, cpc, pc, mo_release, *(a64 **)a, *(a64 *)(a + 8));
}
+# if __TSAN_HAS_INT128
+SANITIZER_INTERFACE_ATTRIBUTE
+void __tsan_go_atomic128_store(ThreadState* thr, uptr cpc, uptr pc, u8* a) {
+ AtomicGo<OpStore>(thr, cpc, pc, mo_release, *(a128**)a, *(a128*)(a + 8));
+}
+# endif
+
SANITIZER_INTERFACE_ATTRIBUTE
void __tsan_go_atomic32_fetch_add(ThreadState *thr, uptr cpc, uptr pc, u8 *a) {
*(a32 *)(a + 16) = AtomicGoRet<OpFetchAdd>(thr, cpc, pc, mo_acq_rel,
@@ -1003,5 +1016,16 @@ void __tsan_go_atomic64_compare_exchange(ThreadState *thr, uptr cpc, uptr pc,
cmp, *(a64 *)(a + 16));
*(bool *)(a + 24) = (cur == cmp);
}
+
+# if __TSAN_HAS_INT128
+SANITIZER_INTERFACE_ATTRIBUTE
+void __tsan_go_atomic128_compare_exchange(ThreadState* thr, uptr cpc, uptr pc,
+ u8* a) {
+ a128 cmp = *(a128*)(a + 8);
+ a128 cur = AtomicGoRet<OpCAS>(thr, cpc, pc, mo_acq_rel, mo_acquire,
+ *(a128**)a, cmp, *(a128*)(a + 24));
+ *(bool*)(a + 40) = (cur == cmp);
+}
+# endif
} // extern "C"
#endif // #if !SANITIZER_GO
More information about the llvm-commits
mailing list