diff --git a/compiler/cbits/genSym.c b/compiler/cbits/genSym.c
index e307432d996069b0d3de97aa05f04293a5895fbb..ee5988ee3ba2499ae328b84b362dc711fe08672b 100644
--- a/compiler/cbits/genSym.c
+++ b/compiler/cbits/genSym.c
@@ -20,10 +20,6 @@ HsInt ghc_unique_inc     = 1;
 #if WORD_SIZE_IN_BITS != 64
 StgWord64 atomic_inc64(StgWord64 volatile* p, StgWord64 incr)
 {
-#if defined(HAVE_C11_ATOMICS)
     return __atomic_fetch_add(p, incr, __ATOMIC_SEQ_CST);
-#else
-    return __sync_fetch_and_add(p, incr);
-#endif
 }
 #endif
diff --git a/libraries/ghc-prim/cbits/atomic.c b/libraries/ghc-prim/cbits/atomic.c
index 6dcb4afb0a90237a2b8a307507846802c0830e2d..fc3e2f8122bef9dc16af7e264881709ad2733afd 100644
--- a/libraries/ghc-prim/cbits/atomic.c
+++ b/libraries/ghc-prim/cbits/atomic.c
@@ -356,44 +356,28 @@ extern StgWord hs_atomicread8(StgWord x);
 StgWord
 hs_atomicread8(StgWord x)
 {
-#if HAVE_C11_ATOMICS
   return __atomic_load_n((StgWord8 *) x, __ATOMIC_SEQ_CST);
-#else
-  return __sync_add_and_fetch((StgWord8 *) x, 0);
-#endif
 }
 
 extern StgWord hs_atomicread16(StgWord x);
 StgWord
 hs_atomicread16(StgWord x)
 {
-#if HAVE_C11_ATOMICS
   return __atomic_load_n((StgWord16 *) x, __ATOMIC_SEQ_CST);
-#else
-  return __sync_add_and_fetch((StgWord16 *) x, 0);
-#endif
 }
 
 extern StgWord hs_atomicread32(StgWord x);
 StgWord
 hs_atomicread32(StgWord x)
 {
-#if HAVE_C11_ATOMICS
   return __atomic_load_n((StgWord32 *) x, __ATOMIC_SEQ_CST);
-#else
-  return __sync_add_and_fetch((StgWord32 *) x, 0);
-#endif
 }
 
 extern StgWord64 hs_atomicread64(StgWord x);
 StgWord64
 hs_atomicread64(StgWord x)
 {
-#if HAVE_C11_ATOMICS
   return __atomic_load_n((StgWord64 *) x, __ATOMIC_SEQ_CST);
-#else
-  return __sync_add_and_fetch((StgWord64 *) x, 0);
-#endif
 }
 
 // AtomicWriteByteArrayOp_Int
@@ -404,44 +388,28 @@ extern void hs_atomicwrite8(StgWord x, StgWord val);
 void
 hs_atomicwrite8(StgWord x, StgWord val)
 {
-#if HAVE_C11_ATOMICS
   __atomic_store_n((StgWord8 *) x, (StgWord8) val, __ATOMIC_SEQ_CST);
-#else
-  while (!__sync_bool_compare_and_swap((StgWord8 *) x, *(StgWord8 *) x, (StgWord8) val));
-#endif
 }
 
 extern void hs_atomicwrite16(StgWord x, StgWord val);
 void
 hs_atomicwrite16(StgWord x, StgWord val)
 {
-#if HAVE_C11_ATOMICS
   __atomic_store_n((StgWord16 *) x, (StgWord16) val, __ATOMIC_SEQ_CST);
-#else
-  while (!__sync_bool_compare_and_swap((StgWord16 *) x, *(StgWord16 *) x, (StgWord16) val));
-#endif
 }
 
 extern void hs_atomicwrite32(StgWord x, StgWord val);
 void
 hs_atomicwrite32(StgWord x, StgWord val)
 {
-#if HAVE_C11_ATOMICS
   __atomic_store_n((StgWord32 *) x, (StgWord32) val, __ATOMIC_SEQ_CST);
-#else
-  while (!__sync_bool_compare_and_swap((StgWord32 *) x, *(StgWord32 *) x, (StgWord32) val));
-#endif
 }
 
 extern void hs_atomicwrite64(StgWord x, StgWord64 val);
 void
 hs_atomicwrite64(StgWord x, StgWord64 val)
 {
-#if HAVE_C11_ATOMICS
   __atomic_store_n((StgWord64 *) x, (StgWord64) val, __ATOMIC_SEQ_CST);
-#else
-  while (!__sync_bool_compare_and_swap((StgWord64 *) x, *(StgWord64 *) x, (StgWord64) val));
-#endif
 }
 
 #endif
diff --git a/rts/configure.ac b/rts/configure.ac
index 6a5e510db0268d5957b822aa79e78e50aee0651c..76d599ec3eab81462d70a292f9badafbebf9428b 100644
--- a/rts/configure.ac
+++ b/rts/configure.ac
@@ -71,7 +71,6 @@ dnl    unregisterised, Sparc, and PPC backends. Also determines whether
 dnl    linking to libatomic is required for atomic operations, e.g. on
 dnl    RISCV64 GCC.
 FP_CC_SUPPORTS__ATOMICS
-AC_DEFINE([HAVE_C11_ATOMICS], [1], [Does C compiler support __atomic primitives?])
 AC_DEFINE_UNQUOTED([NEED_ATOMIC_LIB], [$need_latomic],
     [Define to 1 if we need -latomic for sub-word atomic operations.])
 
diff --git a/rts/include/rts/TSANUtils.h b/rts/include/rts/TSANUtils.h
index 68b223012e296d4e191d486a1070281d74a24c10..40628ef8563fb3ce5a55eef4b42a42ccb887336c 100644
--- a/rts/include/rts/TSANUtils.h
+++ b/rts/include/rts/TSANUtils.h
@@ -75,9 +75,6 @@
 
 #if !defined(CMINUSMINUS)
 #if defined(TSAN_ENABLED)
-#if !defined(HAVE_C11_ATOMICS)
-#error TSAN cannot be enabled without C11 atomics support.
-#endif
 
 #define TSAN_ANNOTATE_HAPPENS_BEFORE(addr)                              \
     AnnotateHappensBefore(__FILE__, __LINE__, (void*)(addr))
diff --git a/rts/include/stg/SMP.h b/rts/include/stg/SMP.h
index 1b9995557324316ed89f1e11ac98faff5dd28f2c..c9111fde7cdab2c0ccb3bec30b082122c325a539 100644
--- a/rts/include/stg/SMP.h
+++ b/rts/include/stg/SMP.h
@@ -442,25 +442,7 @@ EXTERN_INLINE void busy_wait_nop(void);
 EXTERN_INLINE StgWord
 xchg(StgPtr p, StgWord w)
 {
-#if defined(HAVE_C11_ATOMICS)
     return __atomic_exchange_n(p, w, __ATOMIC_SEQ_CST);
-#else
-    // When porting GHC to a new platform check that
-    // __sync_lock_test_and_set() actually stores w in *p.
-    // Use test rts/atomicxchg to verify that the correct value is stored.
-    // From the gcc manual:
-    // (https://gcc.gnu.org/onlinedocs/gcc-4.4.3/gcc/Atomic-Builtins.html)
-    // This built-in function, as described by Intel, is not
-    // a traditional test-and-set operation, but rather an atomic
-    // exchange operation.
-    // [...]
-    // Many targets have only minimal support for such locks,
-    // and do not support a full exchange operation. In this case,
-    // a target may support reduced functionality here by which the
-    // only valid value to store is the immediate constant 1. The
-    // exact value actually stored in *ptr is implementation defined.
-    return __sync_lock_test_and_set(p, w);
-#endif
 }
 
 /*
@@ -470,34 +452,21 @@ xchg(StgPtr p, StgWord w)
 EXTERN_INLINE StgWord
 cas(StgVolatilePtr p, StgWord o, StgWord n)
 {
-#if defined(HAVE_C11_ATOMICS)
     __atomic_compare_exchange_n(p, &o, n, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
     return o;
-#else
-    return __sync_val_compare_and_swap(p, o, n);
-#endif
 }
 
 EXTERN_INLINE StgWord8
 cas_word8(StgWord8 *volatile p, StgWord8 o, StgWord8 n)
 {
-#if defined(HAVE_C11_ATOMICS)
     __atomic_compare_exchange_n(p, &o, n, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
     return o;
-#else
-    return __sync_val_compare_and_swap(p, o, n);
-#endif
 }
 
 EXTERN_INLINE StgWord
 cas_seq_cst_relaxed(StgVolatilePtr p, StgWord o, StgWord n) {
-#if defined(HAVE_C11_ATOMICS)
     __atomic_compare_exchange_n(p, &o, n, 0, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);
     return o;
-#else
-    return __sync_val_compare_and_swap(p, o, n);
-#endif
-
 }
 
 // RRN: Generalized to arbitrary increments to enable fetch-and-add in
@@ -506,21 +475,13 @@ cas_seq_cst_relaxed(StgVolatilePtr p, StgWord o, StgWord n) {
 EXTERN_INLINE StgWord
 atomic_inc(StgVolatilePtr p, StgWord incr)
 {
-#if defined(HAVE_C11_ATOMICS)
     return __atomic_add_fetch(p, incr, __ATOMIC_SEQ_CST);
-#else
-    return __sync_add_and_fetch(p, incr);
-#endif
 }
 
 EXTERN_INLINE StgWord
 atomic_dec(StgVolatilePtr p)
 {
-#if defined(HAVE_C11_ATOMICS)
     return __atomic_sub_fetch(p, 1, __ATOMIC_SEQ_CST);
-#else
-    return __sync_sub_and_fetch(p, (StgWord) 1);
-#endif
 }
 
 /*