Open glaubitz opened 2 years ago
__sync_val_compare_and_swap may be "deprecated", but it should still work.
The SPARC backend should never generate calls to __sync_val_compare_and_swap_8; if it does, that's a bug. (See https://llvm.org/docs/Atomics.html#libcalls-sync .)
Specifically, see: https://github.com/llvm/llvm-project/blob/754d6af7c35983612241b9a077722f4471bbd683/llvm/lib/Target/Sparc/SparcISelLowering.cpp#L1591
Looks like it's calling setMaxAtomicSizeInBitsSupported(64)
on 32-bit targets. I'm pretty sure this is wrong: 32-bit SPARC doesn't have 64-bit atomics.
Hi Eli!
Thanks for looking into this! I have done more research and stumbled over an interesting fact.
On Solaris, 32-bit SPARC uses the V8+ baseline which includes 64-bit atomics.
Quoting from [1]:
With -mv8plus, GCC generates code for the SPARC-V8+ ABI. The difference from the V8 ABI is that the global and out registers are considered 64 bits wide. This is enabled by default on Solaris in 32-bit mode for all SPARC-V9 processors.
However, for gcc, V8+ is not the same as 32-bit V9:
glaubitz@gcc202:~/llvm-project$ echo | gcc -mcpu=v9 -m32 -E -dM -|grep -i SWAP
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
glaubitz@gcc202:~/llvm-project$ echo | gcc -mv8plus -E -dM -|grep -i SWAP
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
glaubitz@gcc202:~/llvm-project$
Thus, the following patch fixes the build with GCC:
diff --git a/compiler-rt/cmake/base-config-ix.cmake b/compiler-rt/cmake/base-config-ix.cmake
index d7b0124f3546..a1dd88da490b 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_COMPILER_IS_GNUCXX)
+ test_target_arch(sparc "" "-m32 -mv8plus")
+ 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
For the stage2 build, one would have to default the 32-bit baseline to V9 as it has been done here [2].
[1] https://gcc.gnu.org/onlinedocs/gcc/SPARC-Options.html [2] https://reviews.llvm.org/D86621
Interesting. Not really relevant, though, unless you're planning to add "-mv8plus" support to LLVM.
Err, wait, the bot is failing stage 1? I was assuming the issue was that clang was generating a call to sync_val_compare_and_swap_8 . Not sure why gcc is generating calls to __sync_val_compare_and_swap_8, instead of using atomic libcalls. If that's the issue, I guess it's okay to work around it in the source code...
Alternatively, maybe consider just disabling the code to generate 32-bit compiler-rt libraries on SPARC.
Err, wait, the bot is failing stage 1? I was assuming the issue was that clang was generating a call to sync_val_compare_and_swap_8 . Not sure why gcc is generating calls to __sync_val_compare_and_swap_8, instead of using atomic libcalls. If that's the issue, I guess it's okay to work around it in the source code...
Exactly. The problem is the bootstrap build with GCC. For the stage2 build, we can just use the approach taken on Solaris [1].
Alternatively, maybe consider just disabling the code to generate 32-bit compiler-rt libraries on SPARC.
I rather want to avoid that. Also, the Solaris maintainers won't like that since Solaris isn't fully 64-bit yet.
What is the current status using 14.0.0?
Ping.
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: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:I would therefore suggest that
compiler-rt
switches to the new built-ins for atomic access.