[compiler-rt] r309974 - [builtins] Use Interlocked* intrinsics for atomics on MSVC

Martin Storsjo via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 3 12:04:28 PDT 2017


Author: mstorsjo
Date: Thu Aug  3 12:04:28 2017
New Revision: 309974

URL: http://llvm.org/viewvc/llvm-project?rev=309974&view=rev
Log:
[builtins] Use Interlocked* intrinsics for atomics on MSVC

Tested on MSVC 2013, 2015 and 2017 targeting X86, X64 and ARM.

This fixes building emutls.c for Windows for ARM (both with clang
which don't need these atomics fallbacks at all, but just failed
due to the immintrin.h include before, and with MSVC).

Differential Revision: https://reviews.llvm.org/D36071

Modified:
    compiler-rt/trunk/lib/builtins/emutls.c

Modified: compiler-rt/trunk/lib/builtins/emutls.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/emutls.c?rev=309974&r1=309973&r2=309974&view=diff
==============================================================================
--- compiler-rt/trunk/lib/builtins/emutls.c (original)
+++ compiler-rt/trunk/lib/builtins/emutls.c Thu Aug  3 12:04:28 2017
@@ -102,7 +102,6 @@ static __inline emutls_address_array* em
 #include <malloc.h>
 #include <stdio.h>
 #include <assert.h>
-#include <immintrin.h>
 
 static LPCRITICAL_SECTION emutls_mutex;
 static DWORD emutls_tls_index = TLS_OUT_OF_INDEXES;
@@ -203,25 +202,24 @@ static __inline emutls_address_array* em
 /* Provide atomic load/store functions for emutls_get_index if built with MSVC.
  */
 #if !defined(__ATOMIC_RELEASE)
+#include <intrin.h>
 
 enum { __ATOMIC_ACQUIRE = 2, __ATOMIC_RELEASE = 3 };
 
 static __inline uintptr_t __atomic_load_n(void *ptr, unsigned type) {
     assert(type == __ATOMIC_ACQUIRE);
+    // These return the previous value - but since we do an OR with 0,
+    // it's equivalent to a plain load.
 #ifdef _WIN64
-    return (uintptr_t) _load_be_u64(ptr);
+    return InterlockedOr64(ptr, 0);
 #else
-    return (uintptr_t) _load_be_u32(ptr);
+    return InterlockedOr(ptr, 0);
 #endif
 }
 
 static __inline void __atomic_store_n(void *ptr, uintptr_t val, unsigned type) {
     assert(type == __ATOMIC_RELEASE);
-#ifdef _WIN64
-    _store_be_u64(ptr, val);
-#else
-    _store_be_u32(ptr, val);
-#endif
+    InterlockedExchangePointer((void *volatile *)ptr, (void *)val);
 }
 
 #endif




More information about the llvm-commits mailing list