As discussed in D118021, clang -m32 on Solaris/sparcv9 currently incorrectly doesn't
inline atomics on 8-byte operands, unlike gcc. With the workaround in that patch in place,
we're left with may undefined references to __sync_val_compare_and_swap_8, which
isn't provided by libatomic. This reference is due to the use of __sync_val_compare_and_swap in sanitizer_atomic_clang.h's atomic_compare_exchange_strong.
As is already done in scudo/standalone/atomic_helpers.h, using __atomic_compare_exchange instead avoids this problem.
Tested on sparcv9-sun-solaris2.11, amd64-pc-solaris2.11, and x86_64-pc-linux-gnu.
However, there are two issues here:
- In a 2-stage build with GCC 11 as stage 1 compiler, it warns
/vol/llvm/src/llvm-project/local/compiler-rt/lib/asan/../sanitizer_common/sanitizer_atomic_clang.h:86:35: warning: invalid memory model argument to builtin [-Winvalid-memory-model] 86 | return __atomic_compare_exchange(&a->val_dont_use, cmp, &xchg, false, mo, | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 87 | __ATOMIC_RELAXED); | ~~~~~~~~~~~~~~~~~
According to [[ https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html#g_t_005f_005fatomic-Builtins | Built-in Functions for Memory Model Aware Atomic Operations ]], the `__atomic_*` builtins map runtime-variable memory order parameters to `__ATOMIC_SEQ_CST`. However, with `mo, __ATOMIC_SEQ_CST`, `gcc` still warns
/vol/llvm/src/llvm-project/local/compiler-rt/lib/asan/../sanitizer_common/sanitizer_atomic_clang.h:86:35: warning: failure memory model cannot be stronger than success memory model for ‘__atomic_compare_exchange’ [-Winvalid-memory-model] 86 | return __atomic_compare_exchange(&a->val_dont_use, cmp, &xchg, false, mo, | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 87 | __ATOMIC_SEQ_CST); | ~~~~~~~~~~~~~~~~~
Only with ` __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST` the warning vanishes.
- With any of the three variants above, on Solaris/sparcv9 three tests regress with this patch:
SanitizerCommon-Unit :: ./Sanitizer-sparc-Test/DenseMapCustomTest.DefaultMinRe servedSizeTest SanitizerCommon-Unit :: ./Sanitizer-sparcv9-Test/CompactRingBuffer.int64 SanitizerCommon-Unit :: ./Sanitizer-sparcv9-Test/DenseMapCustomTest.DefaultMin ReservedSizeTest
There's no such regression on x86, though.
Please don't change the memory ordering in this patch. (__sync_* is sequentially consistent.) If you really want to change it, please post as a separate patch with an appropriate title.