summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-03-21 14:28:55 +0000
committerDmitry Vyukov <dvyukov@google.com>2017-03-21 14:28:55 +0000
commitde033e6cdbf10b979c65229fe5626572a3a8735d (patch)
tree0c63a667a133ef862daec6d159dba9264e094d6a
parent00ece756c32f35afa70421479635a679e0947697 (diff)
downloadbcm5719-llvm-de033e6cdbf10b979c65229fe5626572a3a8735d.tar.gz
bcm5719-llvm-de033e6cdbf10b979c65229fe5626572a3a8735d.zip
tsan: support __ATOMIC_HLE_ACQUIRE/RELEASE flags
HLE flags can be combined with memory order in atomic operations. Currently tsan runtime crashes on e.g. IsStoreOrder(mo) in atomic store if any of these additional flags are specified. Filter these flags out. See the comment as to why it is safe. llvm-svn: 298378
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_interface_atomic.cc19
-rw-r--r--compiler-rt/test/tsan/atomic_hle.cc25
2 files changed, 43 insertions, 1 deletions
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interface_atomic.cc b/compiler-rt/lib/tsan/rtl/tsan_interface_atomic.cc
index 5238b66a2e5..e49e1d2c5c3 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interface_atomic.cc
+++ b/compiler-rt/lib/tsan/rtl/tsan_interface_atomic.cc
@@ -450,10 +450,27 @@ static void AtomicFence(ThreadState *thr, uptr pc, morder mo) {
// C/C++
+static morder covert_morder(morder mo) {
+ if (flags()->force_seq_cst_atomics)
+ return (morder)mo_seq_cst;
+
+ // Filter out additional memory order flags:
+ // MEMMODEL_SYNC = 1 << 15
+ // __ATOMIC_HLE_ACQUIRE = 1 << 16
+ // __ATOMIC_HLE_RELEASE = 1 << 17
+ //
+ // HLE is an optimization, and we pretend that elision always fails.
+ // MEMMODEL_SYNC is used when lowering __sync_ atomics,
+ // since we use __sync_ atomics for actual atomic operations,
+ // we can safely ignore it as well. It also subtly affects semantics,
+ // but we don't model the difference.
+ return (morder)(mo & 0x7fff);
+}
+
#define SCOPED_ATOMIC(func, ...) \
const uptr callpc = (uptr)__builtin_return_address(0); \
uptr pc = StackTrace::GetCurrentPc(); \
- mo = flags()->force_seq_cst_atomics ? (morder)mo_seq_cst : mo; \
+ mo = covert_morder(mo); \
ThreadState *const thr = cur_thread(); \
if (thr->ignore_interceptors) \
return NoTsanAtomic##func(__VA_ARGS__); \
diff --git a/compiler-rt/test/tsan/atomic_hle.cc b/compiler-rt/test/tsan/atomic_hle.cc
new file mode 100644
index 00000000000..345e363c2bc
--- /dev/null
+++ b/compiler-rt/test/tsan/atomic_hle.cc
@@ -0,0 +1,25 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+#include "test.h"
+#include <sanitizer/tsan_interface_atomic.h>
+
+#ifndef __ATOMIC_HLE_ACQUIRE
+#define __ATOMIC_HLE_ACQUIRE (1 << 16)
+#endif
+#ifndef __ATOMIC_HLE_RELEASE
+#define __ATOMIC_HLE_RELEASE (1 << 17)
+#endif
+
+int main() {
+ volatile int x = 0;
+ //__atomic_fetch_add(&x, 1, __ATOMIC_ACQUIRE | __ATOMIC_HLE_ACQUIRE);
+ //__atomic_store_n(&x, 0, __ATOMIC_RELEASE | __ATOMIC_HLE_RELEASE);
+ __tsan_atomic32_fetch_add(&x, 1,
+ (__tsan_memory_order)(__ATOMIC_ACQUIRE | __ATOMIC_HLE_ACQUIRE));
+ __tsan_atomic32_store(&x, 0,
+ (__tsan_memory_order)(__ATOMIC_RELEASE | __ATOMIC_HLE_RELEASE));
+ fprintf(stderr, "DONE\n");
+ return 0;
+}
+
+// CHECK: DONE
+
OpenPOWER on IntegriCloud