Use double-word atomic intrinsics for recent Clang versions (gcc/x86.h)
authorIvan Maidanski <ivmai@mail.ru>
Fri, 8 Dec 2017 17:02:48 +0000 (20:02 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Fri, 22 Dec 2017 07:45:15 +0000 (10:45 +0300)
Older clang versions have some bugs or limitations that prevent from
using double-word built-in atomic operations.

Note: even as of clang-4.0, there seems to be a bug in some
double-word built-in operation if Thread Sanitizer is used.

* src/atomic_ops/sysdeps/gcc/x86.h [AO_GCC_ATOMIC_TEST_AND_SET
&& __APPLE_CC__ && __x86_64__]
(AO_SKIPATOMIC_double_compare_and_swap_ANY): Do not define if
AO_CLANG_PREREQ(9, 0); update comment.
* src/atomic_ops/sysdeps/gcc/x86.h [AO_GCC_ATOMIC_TEST_AND_SET
&& !__APPLE_CC__ && __clang__ && !__x86_64__
&& !AO_PREFER_BUILTIN_ATOMICS && !__CYGWIN__]
(AO_SKIPATOMIC_double_compare_and_swap_ANY,
AO_SKIPATOMIC_DOUBLE_LOAD_STORE_ANY): Do not define if
AO_CLANG_PREREQ(5, 0); update comment.
* src/atomic_ops/sysdeps/gcc/x86.h [AO_GCC_ATOMIC_TEST_AND_SET
&& !__APPLE_CC__ && __clang__ && __x86_64__ && !__ILP32__
&& AO_ADDRESS_SANITIZER] (AO_SKIPATOMIC_double_compare_and_swap_ANY
AO_SKIPATOMIC_DOUBLE_LOAD_STORE_ANY): Do not define if
AO_CLANG_PREREQ(4, 0); update comment.

src/atomic_ops/sysdeps/gcc/x86.h

index 7a7c689..e4863ad 100644 (file)
 #   define AO_GCC_FORCE_HAVE_CAS
 
 #   ifdef __x86_64__
-      /* As of Apple clang-600 (based on LLVM 3.5svn), it has some bug  */
-      /* in the double-wide CAS implementation for x64 target.          */
-      /* TODO: Refine for newer Apple clang releases. */
+#     if !AO_CLANG_PREREQ(9, 0) /* < Apple clang-900 */
+        /* Older Apple clang (e.g., clang-600 based on LLVM 3.5svn) had */
+        /* some bug in the double word CAS implementation for x64.      */
 #       define AO_SKIPATOMIC_double_compare_and_swap_ANY
+#     endif
 
 #   elif defined(__MACH__)
       /* OS X 10.8 lacks __atomic_load/store symbols for arch i386      */
 
 # elif defined(__clang__)
 #   if !defined(__x86_64__)
-#     if !defined(AO_PREFER_BUILTIN_ATOMICS) && !defined(__CYGWIN__)
-        /* As of clang-3.8/i686 (NDK r11c), it requires -latomic for    */
-        /* all the double-wide operations.  For now, we fall back to    */
-        /* the non-intrinsic implementation by default.                 */
-        /* TODO: Refine for newer clang releases. */
+#     if !defined(AO_PREFER_BUILTIN_ATOMICS) && !defined(__CYGWIN__) \
+         && !AO_CLANG_PREREQ(5, 0)
+        /* At least clang-3.8/i686 (from NDK r11c) required to specify  */
+        /* -latomic in case of a double-word atomic operation use.      */
 #       define AO_SKIPATOMIC_double_compare_and_swap_ANY
 #       define AO_SKIPATOMIC_DOUBLE_LOAD_STORE_ANY
 #     endif /* !AO_PREFER_BUILTIN_ATOMICS */
 
 #   elif !defined(__ILP32__)
 #     if (!AO_CLANG_PREREQ(3, 5) && !defined(AO_PREFER_BUILTIN_ATOMICS)) \
-         || defined(AO_ADDRESS_SANITIZER) || defined(AO_THREAD_SANITIZER)
-        /* Same as above but for clang-3.4/x64.  As of clang-4.0,       */
-        /* double-wide arguments are incorrectly passed to atomic       */
-        /* intrinsic operations for x64 target if ASan/TSan enabled.    */
+         || (!AO_CLANG_PREREQ(4, 0) && defined(AO_ADDRESS_SANITIZER)) \
+         || defined(AO_THREAD_SANITIZER)
+        /* clang-3.4/x64 required -latomic.  clang-3.9/x64 seems to     */
+        /* pass double-wide arguments to atomic operations incorrectly  */
+        /* in case of ASan/TSan.                                        */
+        /* TODO: As of clang-4.0, lock-free test_stack fails if TSan.   */
 #       define AO_SKIPATOMIC_double_compare_and_swap_ANY
 #       define AO_SKIPATOMIC_DOUBLE_LOAD_STORE_ANY
 #     endif