diff --git a/rts/TSANUtils.c b/rts/TSANUtils.c
index 790381acdb9bffddaea1662c06ee0a9baba13087..02d18a8fe70a5bd0e057c167a1061c308d14d035 100644
--- a/rts/TSANUtils.c
+++ b/rts/TSANUtils.c
@@ -2,7 +2,7 @@
 
 #if defined(TSAN_ENABLED)
 
-uint64_t ghc_tsan_atomic64_compare_exchange(uint64_t *ptr, uint64_t expected, uint64_t new_value, int success_memorder, int failure_memorder)
+__tsan_atomic64 ghc_tsan_atomic64_compare_exchange(volatile __tsan_atomic64 *ptr, __tsan_atomic64 expected, __tsan_atomic64 new_value, int success_memorder, int failure_memorder)
 {
     __tsan_atomic64_compare_exchange_strong(
             ptr, &expected, new_value,
@@ -10,7 +10,7 @@ uint64_t ghc_tsan_atomic64_compare_exchange(uint64_t *ptr, uint64_t expected, ui
     return expected;
 }
 
-uint32_t ghc_tsan_atomic32_compare_exchange(uint32_t *ptr, uint32_t expected, uint32_t new_value, int success_memorder, int failure_memorder)
+__tsan_atomic32 ghc_tsan_atomic32_compare_exchange(volatile __tsan_atomic32 *ptr, __tsan_atomic32 expected, __tsan_atomic32 new_value, int success_memorder, int failure_memorder)
 {
     __tsan_atomic32_compare_exchange_strong(
             ptr, &expected, new_value,
@@ -18,7 +18,7 @@ uint32_t ghc_tsan_atomic32_compare_exchange(uint32_t *ptr, uint32_t expected, ui
     return expected;
 }
 
-uint16_t ghc_tsan_atomic16_compare_exchange(uint16_t *ptr, uint16_t expected, uint16_t new_value, int success_memorder, int failure_memorder)
+__tsan_atomic16 ghc_tsan_atomic16_compare_exchange(volatile __tsan_atomic16 *ptr, __tsan_atomic16 expected, __tsan_atomic16 new_value, int success_memorder, int failure_memorder)
 {
     __tsan_atomic16_compare_exchange_strong(
             ptr, &expected, new_value,
@@ -26,7 +26,7 @@ uint16_t ghc_tsan_atomic16_compare_exchange(uint16_t *ptr, uint16_t expected, ui
     return expected;
 }
 
-uint8_t ghc_tsan_atomic8_compare_exchange(uint8_t *ptr, uint8_t expected, uint8_t new_value, int success_memorder, int failure_memorder)
+__tsan_atomic8 ghc_tsan_atomic8_compare_exchange(volatile __tsan_atomic8 *ptr, __tsan_atomic8 expected, __tsan_atomic8 new_value, int success_memorder, int failure_memorder)
 {
     __tsan_atomic8_compare_exchange_strong(
             ptr, &expected, new_value,
diff --git a/rts/include/rts/TSANUtils.h b/rts/include/rts/TSANUtils.h
index 40628ef8563fb3ce5a55eef4b42a42ccb887336c..acdb3ccee4a0407efb909a1bd51775d4ceb3e053 100644
--- a/rts/include/rts/TSANUtils.h
+++ b/rts/include/rts/TSANUtils.h
@@ -98,10 +98,18 @@ void AnnotateBenignRaceSized(const char *file,
 #define TSAN_ANNOTATE_BENIGN_RACE(addr,desc)                            \
     TSAN_ANNOTATE_BENIGN_RACE_SIZED((void*)(addr), sizeof(*addr), desc)
 
+#if defined(TSAN_ENABLED) && defined(__clang__)
+#include <sanitizer/tsan_interface_atomic.h>
+#else
+typedef char __tsan_atomic8;
+typedef short __tsan_atomic16;
+typedef int __tsan_atomic32;
+typedef long __tsan_atomic64;
+#endif
 
-uint64_t ghc_tsan_atomic64_compare_exchange(uint64_t *ptr, uint64_t expected, uint64_t new_value, int success_memorder, int failure_memorder);
-uint32_t ghc_tsan_atomic32_compare_exchange(uint32_t *ptr, uint32_t expected, uint32_t new_value, int success_memorder, int failure_memorder);
-uint16_t ghc_tsan_atomic16_compare_exchange(uint16_t *ptr, uint16_t expected, uint16_t new_value, int success_memorder, int failure_memorder);
-uint8_t ghc_tsan_atomic8_compare_exchange(uint8_t *ptr, uint8_t expected, uint8_t new_value, int success_memorder, int failure_memorder);
+__tsan_atomic64 ghc_tsan_atomic64_compare_exchange(volatile __tsan_atomic64 *ptr, __tsan_atomic64 expected, __tsan_atomic64 new_value, int success_memorder, int failure_memorder);
+__tsan_atomic32 ghc_tsan_atomic32_compare_exchange(volatile __tsan_atomic32 *ptr, __tsan_atomic32 expected, __tsan_atomic32 new_value, int success_memorder, int failure_memorder);
+__tsan_atomic16 ghc_tsan_atomic16_compare_exchange(volatile __tsan_atomic16 *ptr, __tsan_atomic16 expected, __tsan_atomic16 new_value, int success_memorder, int failure_memorder);
+__tsan_atomic8 ghc_tsan_atomic8_compare_exchange(volatile __tsan_atomic8 *ptr, __tsan_atomic8 expected, __tsan_atomic8 new_value, int success_memorder, int failure_memorder);
 
 #endif
diff --git a/rts/include/stg/SMP.h b/rts/include/stg/SMP.h
index 22edad0e167e572b96e64c46492d249b34d44a9c..02a95badf8c20dfdd1f2eaf8a287c06204285211 100644
--- a/rts/include/stg/SMP.h
+++ b/rts/include/stg/SMP.h
@@ -549,12 +549,14 @@ busy_wait_nop(void)
 #define SEQ_CST_FENCE() __atomic_thread_fence(__ATOMIC_SEQ_CST)
 
 #if defined(TSAN_ENABLED)
+#if !defined(__clang__)
 #undef ACQUIRE_FENCE
 #undef RELEASE_FENCE
 #undef SEQ_CST_FENCE
 #define ACQUIRE_FENCE() NO_WARN(-Wtsan, __atomic_thread_fence(__ATOMIC_ACQUIRE);)
 #define RELEASE_FENCE() NO_WARN(-Wtsan, __atomic_thread_fence(__ATOMIC_RELEASE);)
 #define SEQ_CST_FENCE() NO_WARN(-Wtsan, __atomic_thread_fence(__ATOMIC_SEQ_CST);)
+#endif
 #define ACQUIRE_FENCE_ON(x) (void)ACQUIRE_LOAD(x)
 #else
 #define ACQUIRE_FENCE_ON(x) __atomic_thread_fence(__ATOMIC_ACQUIRE)
diff --git a/rts/rts.cabal b/rts/rts.cabal
index 0083697a70d62dcb9940acd827f92b7068fee81b..4e4ddfb52f066350f74595080582f1d460fbdf68 100644
--- a/rts/rts.cabal
+++ b/rts/rts.cabal
@@ -184,7 +184,6 @@ library
       if flag(thread-sanitizer)
         cc-options: -fsanitize=thread
         ld-options: -fsanitize=thread
-        extra-libraries: tsan
 
       if os(linux)
          -- the RTS depends upon libc. while this dependency is generally