Skip to content

compiler-rt uses deprecated built-ins for atomic access #53337

@glaubitz

Description

@glaubitz

I have been trying to fix the failing builds on the buildbot clang-sparc64-linux-multistage [1] for quite some time now.

The reason for the failure is that the linker cannot find __sync_val_compare_and_swap_8 when building on 32-bit SPARC which is not available on this target:

/usr/bin/ld: warning: -z gnu-version-script-compat ignored
/usr/bin/ld: projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.sparc.dir/sanitizer_libignore.cpp.o: in function `bool __sanitizer::atomic_compare_exchange_strong<__sanitizer::atomic_uint64_t>(__sanitizer::atomic_uint64_t volatile*, __sanitizer::atomic_uint64_t::Type*, __sanitizer::atomic_uint64_t::Type, __sanitizer::memory_order)':
/var/lib/buildbot/workers/debian-stadler-sparc64/clang-sparc64-linux-multistage/llvm/compiler-rt/lib/sanitizer_common/sanitizer_atomic_clang.h:80: undefined reference to `__sync_val_compare_and_swap_8'

According to a bug report in GCC, the atomic built-ins __sync_(...) [3] are considered deprecated and have been superseded by the __atomic_(...) built-ins [4].

And, in fact, the following simple hack fixes the build of compiler-rt on 32-bit SPARC on Linux:

diff --git a/compiler-rt/cmake/base-config-ix.cmake b/compiler-rt/cmake/base-config-ix.cmake
index d7b0124f3546..266011ebdeee 100644
--- a/compiler-rt/cmake/base-config-ix.cmake
+++ b/compiler-rt/cmake/base-config-ix.cmake
@@ -206,7 +206,11 @@ macro(test_targets)
     elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "s390x")
       test_target_arch(s390x "" "")
     elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "sparc")
-      test_target_arch(sparc "" "-m32")
+      if(CMAKE_SYSTEM_NAME MATCHES "Linux")
+       test_target_arch(sparc "" "-m32 -latomic")
+      else()
+       test_target_arch(sparc "" "-m32")
+      endif()
       test_target_arch(sparcv9 "" "-m64")
     elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "mipsel|mips64el")
       # Gcc doesn't accept -m32/-m64 so we do the next best thing and use
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_atomic_clang.h b/compiler-rt/lib/sanitizer_common/sanitizer_atomic_clang.h
index fc13ca52dda7..bfe30c775663 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_atomic_clang.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_atomic_clang.h
@@ -77,7 +77,7 @@ inline bool atomic_compare_exchange_strong(volatile T *a, typename T::Type *cmp,
   typedef typename T::Type Type;
   Type cmpv = *cmp;
   Type prev;
-  prev = __sync_val_compare_and_swap(&a->val_dont_use, cmpv, xchg);
+  prev = __atomic_compare_exchange(&a->val_dont_use, &cmpv, &xchg, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
   if (prev == cmpv) return true;
   *cmp = prev;
   return false;

I would therefore suggest that compiler-rt switches to the new built-ins for atomic access.

[1] https://lab.llvm.org/staging/#/builders/113
[2] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63368
[3] https://gcc.gnu.org/onlinedocs/gcc-4.5.3/gcc/Atomic-Builtins.html
[4] https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions