Revert "[InstCombine] Support gep nuw in icmp folds" (#118698)
[llvm-project.git] / compiler-rt / lib / sanitizer_common / tests / sanitizer_atomic_test.cpp
bloba3e309fdbd3ac31c7ceaaa93aa4bf5bf512a4612
1 //===-- sanitizer_atomic_test.cpp -----------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file is a part of ThreadSanitizer/AddressSanitizer runtime.
11 //===----------------------------------------------------------------------===//
12 #include "sanitizer_common/sanitizer_atomic.h"
13 #include "gtest/gtest.h"
15 #ifndef __has_extension
16 #define __has_extension(x) 0
17 #endif
19 #ifndef ATOMIC_LLONG_LOCK_FREE
20 # if __has_extension(c_atomic) || __has_extension(cxx_atomic)
21 # define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE
22 # elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
23 # define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
24 # else
25 # error Unsupported compiler.
26 # endif
27 #endif
29 namespace __sanitizer {
31 template<typename T>
32 struct ValAndMagic {
33 typename T::Type magic0;
34 T a;
35 typename T::Type magic1;
37 static ValAndMagic<T> *sink;
40 template<typename T>
41 ValAndMagic<T> *ValAndMagic<T>::sink;
43 template<typename T, memory_order load_mo, memory_order store_mo>
44 void CheckStoreLoad() {
45 typedef typename T::Type Type;
46 ValAndMagic<T> val;
47 // Prevent the compiler from scalarizing the struct.
48 ValAndMagic<T>::sink = &val;
49 // Ensure that surrounding memory is not overwritten.
50 val.magic0 = val.magic1 = (Type)-3;
51 for (u64 i = 0; i < 100; i++) {
52 // Generate a value that occupies all bytes of the variable.
53 u64 v = i;
54 v |= v << 8;
55 v |= v << 16;
56 v |= v << 32;
57 val.a.val_dont_use = (Type)v;
58 EXPECT_EQ(atomic_load(&val.a, load_mo), (Type)v);
59 val.a.val_dont_use = (Type)-1;
60 atomic_store(&val.a, (Type)v, store_mo);
61 EXPECT_EQ(val.a.val_dont_use, (Type)v);
63 EXPECT_EQ(val.magic0, (Type)-3);
64 EXPECT_EQ(val.magic1, (Type)-3);
67 TEST(SanitizerCommon, AtomicStoreLoad) {
68 CheckStoreLoad<atomic_uint8_t, memory_order_relaxed, memory_order_relaxed>();
69 CheckStoreLoad<atomic_uint8_t, memory_order_consume, memory_order_relaxed>();
70 CheckStoreLoad<atomic_uint8_t, memory_order_acquire, memory_order_relaxed>();
71 CheckStoreLoad<atomic_uint8_t, memory_order_relaxed, memory_order_release>();
72 CheckStoreLoad<atomic_uint8_t, memory_order_seq_cst, memory_order_seq_cst>();
74 CheckStoreLoad<atomic_uint16_t, memory_order_relaxed, memory_order_relaxed>();
75 CheckStoreLoad<atomic_uint16_t, memory_order_consume, memory_order_relaxed>();
76 CheckStoreLoad<atomic_uint16_t, memory_order_acquire, memory_order_relaxed>();
77 CheckStoreLoad<atomic_uint16_t, memory_order_relaxed, memory_order_release>();
78 CheckStoreLoad<atomic_uint16_t, memory_order_seq_cst, memory_order_seq_cst>();
80 CheckStoreLoad<atomic_uint32_t, memory_order_relaxed, memory_order_relaxed>();
81 CheckStoreLoad<atomic_uint32_t, memory_order_consume, memory_order_relaxed>();
82 CheckStoreLoad<atomic_uint32_t, memory_order_acquire, memory_order_relaxed>();
83 CheckStoreLoad<atomic_uint32_t, memory_order_relaxed, memory_order_release>();
84 CheckStoreLoad<atomic_uint32_t, memory_order_seq_cst, memory_order_seq_cst>();
86 // Avoid fallbacking to software emulated compiler atomics, that are usually
87 // provided by libatomic, which is not always present.
88 #if ATOMIC_LLONG_LOCK_FREE == 2
89 CheckStoreLoad<atomic_uint64_t, memory_order_relaxed, memory_order_relaxed>();
90 CheckStoreLoad<atomic_uint64_t, memory_order_consume, memory_order_relaxed>();
91 CheckStoreLoad<atomic_uint64_t, memory_order_acquire, memory_order_relaxed>();
92 CheckStoreLoad<atomic_uint64_t, memory_order_relaxed, memory_order_release>();
93 CheckStoreLoad<atomic_uint64_t, memory_order_seq_cst, memory_order_seq_cst>();
94 #endif
96 CheckStoreLoad<atomic_uintptr_t, memory_order_relaxed, memory_order_relaxed>
97 ();
98 CheckStoreLoad<atomic_uintptr_t, memory_order_consume, memory_order_relaxed>
99 ();
100 CheckStoreLoad<atomic_uintptr_t, memory_order_acquire, memory_order_relaxed>
102 CheckStoreLoad<atomic_uintptr_t, memory_order_relaxed, memory_order_release>
104 CheckStoreLoad<atomic_uintptr_t, memory_order_seq_cst, memory_order_seq_cst>
108 // Clang crashes while compiling this test for Android:
109 // http://llvm.org/bugs/show_bug.cgi?id=15587
110 #if !SANITIZER_ANDROID
111 template<typename T>
112 void CheckAtomicCompareExchange() {
113 typedef typename T::Type Type;
115 Type old_val = 42;
116 Type new_val = 24;
117 Type var = old_val;
118 EXPECT_TRUE(atomic_compare_exchange_strong((T*)&var, &old_val, new_val,
119 memory_order_relaxed));
120 EXPECT_FALSE(atomic_compare_exchange_strong((T*)&var, &old_val, new_val,
121 memory_order_relaxed));
122 EXPECT_EQ(new_val, old_val);
125 Type old_val = 42;
126 Type new_val = 24;
127 Type var = old_val;
128 EXPECT_TRUE(atomic_compare_exchange_weak((T*)&var, &old_val, new_val,
129 memory_order_relaxed));
130 EXPECT_FALSE(atomic_compare_exchange_weak((T*)&var, &old_val, new_val,
131 memory_order_relaxed));
132 EXPECT_EQ(new_val, old_val);
136 TEST(SanitizerCommon, AtomicCompareExchangeTest) {
137 CheckAtomicCompareExchange<atomic_uint8_t>();
138 CheckAtomicCompareExchange<atomic_uint16_t>();
139 CheckAtomicCompareExchange<atomic_uint32_t>();
140 #if ATOMIC_LLONG_LOCK_FREE == 2
141 CheckAtomicCompareExchange<atomic_uint64_t>();
142 #endif
143 CheckAtomicCompareExchange<atomic_uintptr_t>();
145 #endif //!SANITIZER_ANDROID
147 } // namespace __sanitizer