321 lines · c
1// Test frontend handling of __sync builtins.2// Modified from a gcc testcase.3// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - | FileCheck %s4 5signed char sc;6unsigned char uc;7signed short ss;8unsigned short us;9signed int si;10unsigned int ui;11signed long long sll;12unsigned long long ull;13__int128 s128;14unsigned __int128 u128;15 16void test_op_ignore (void) // CHECK-LABEL: define{{.*}} void @test_op_ignore17{18 (void) __sync_fetch_and_add (&sc, 1); // CHECK: atomicrmw add ptr {{.*}} seq_cst, align 119 (void) __sync_fetch_and_add (&uc, 1); // CHECK: atomicrmw add ptr {{.*}} seq_cst, align 120 (void) __sync_fetch_and_add (&ss, 1); // CHECK: atomicrmw add ptr {{.*}} seq_cst, align 221 (void) __sync_fetch_and_add (&us, 1); // CHECK: atomicrmw add ptr {{.*}} seq_cst, align 222 (void) __sync_fetch_and_add (&si, 1); // CHECK: atomicrmw add ptr {{.*}} seq_cst, align 423 (void) __sync_fetch_and_add (&ui, 1); // CHECK: atomicrmw add ptr {{.*}} seq_cst, align 424 (void) __sync_fetch_and_add (&sll, 1); // CHECK: atomicrmw add ptr {{.*}} seq_cst, align 825 (void) __sync_fetch_and_add (&ull, 1); // CHECK: atomicrmw add ptr {{.*}} seq_cst, align 826 27 (void) __sync_fetch_and_sub (&sc, 1); // CHECK: atomicrmw sub ptr {{.*}} seq_cst, align 128 (void) __sync_fetch_and_sub (&uc, 1); // CHECK: atomicrmw sub ptr {{.*}} seq_cst, align 129 (void) __sync_fetch_and_sub (&ss, 1); // CHECK: atomicrmw sub ptr {{.*}} seq_cst, align 230 (void) __sync_fetch_and_sub (&us, 1); // CHECK: atomicrmw sub ptr {{.*}} seq_cst, align 231 (void) __sync_fetch_and_sub (&si, 1); // CHECK: atomicrmw sub ptr {{.*}} seq_cst, align 432 (void) __sync_fetch_and_sub (&ui, 1); // CHECK: atomicrmw sub ptr {{.*}} seq_cst, align 433 (void) __sync_fetch_and_sub (&sll, 1); // CHECK: atomicrmw sub ptr {{.*}} seq_cst, align 834 (void) __sync_fetch_and_sub (&ull, 1); // CHECK: atomicrmw sub ptr {{.*}} seq_cst, align 835 36 (void) __sync_fetch_and_or (&sc, 1); // CHECK: atomicrmw or ptr {{.*}} seq_cst, align 137 (void) __sync_fetch_and_or (&uc, 1); // CHECK: atomicrmw or ptr {{.*}} seq_cst, align 138 (void) __sync_fetch_and_or (&ss, 1); // CHECK: atomicrmw or ptr {{.*}} seq_cst, align 239 (void) __sync_fetch_and_or (&us, 1); // CHECK: atomicrmw or ptr {{.*}} seq_cst, align 240 (void) __sync_fetch_and_or (&si, 1); // CHECK: atomicrmw or ptr {{.*}} seq_cst, align 441 (void) __sync_fetch_and_or (&ui, 1); // CHECK: atomicrmw or ptr {{.*}} seq_cst, align 442 (void) __sync_fetch_and_or (&sll, 1); // CHECK: atomicrmw or ptr {{.*}} seq_cst, align 843 (void) __sync_fetch_and_or (&ull, 1); // CHECK: atomicrmw or ptr {{.*}} seq_cst, align 844 45 (void) __sync_fetch_and_xor (&sc, 1); // CHECK: atomicrmw xor ptr {{.*}} seq_cst, align 146 (void) __sync_fetch_and_xor (&uc, 1); // CHECK: atomicrmw xor ptr {{.*}} seq_cst, align 147 (void) __sync_fetch_and_xor (&ss, 1); // CHECK: atomicrmw xor ptr {{.*}} seq_cst, align 248 (void) __sync_fetch_and_xor (&us, 1); // CHECK: atomicrmw xor ptr {{.*}} seq_cst, align 249 (void) __sync_fetch_and_xor (&si, 1); // CHECK: atomicrmw xor ptr {{.*}} seq_cst, align 450 (void) __sync_fetch_and_xor (&ui, 1); // CHECK: atomicrmw xor ptr {{.*}} seq_cst, align 451 (void) __sync_fetch_and_xor (&sll, 1); // CHECK: atomicrmw xor ptr {{.*}} seq_cst, align 852 (void) __sync_fetch_and_xor (&ull, 1); // CHECK: atomicrmw xor ptr {{.*}} seq_cst, align 853 (void) __sync_fetch_and_xor (&u128, 1); // CHECK: atomicrmw xor ptr {{.*}} seq_cst, align 1654 (void) __sync_fetch_and_xor (&s128, 1); // CHECK: atomicrmw xor ptr {{.*}} seq_cst, align 1655 56 (void) __sync_fetch_and_nand (&sc, 1); // CHECK: atomicrmw nand ptr {{.*}} seq_cst, align 157 (void) __sync_fetch_and_nand (&uc, 1); // CHECK: atomicrmw nand ptr {{.*}} seq_cst, align 158 (void) __sync_fetch_and_nand (&ss, 1); // CHECK: atomicrmw nand ptr {{.*}} seq_cst, align 259 (void) __sync_fetch_and_nand (&us, 1); // CHECK: atomicrmw nand ptr {{.*}} seq_cst, align 260 (void) __sync_fetch_and_nand (&si, 1); // CHECK: atomicrmw nand ptr {{.*}} seq_cst, align 461 (void) __sync_fetch_and_nand (&ui, 1); // CHECK: atomicrmw nand ptr {{.*}} seq_cst, align 462 (void) __sync_fetch_and_nand (&sll, 1); // CHECK: atomicrmw nand ptr {{.*}} seq_cst, align 863 (void) __sync_fetch_and_nand (&ull, 1); // CHECK: atomicrmw nand ptr {{.*}} seq_cst, align 864 65 (void) __sync_fetch_and_and (&sc, 1); // CHECK: atomicrmw and ptr {{.*}} seq_cst, align 166 (void) __sync_fetch_and_and (&uc, 1); // CHECK: atomicrmw and ptr {{.*}} seq_cst, align 167 (void) __sync_fetch_and_and (&ss, 1); // CHECK: atomicrmw and ptr {{.*}} seq_cst, align 268 (void) __sync_fetch_and_and (&us, 1); // CHECK: atomicrmw and ptr {{.*}} seq_cst, align 269 (void) __sync_fetch_and_and (&si, 1); // CHECK: atomicrmw and ptr {{.*}} seq_cst, align 470 (void) __sync_fetch_and_and (&ui, 1); // CHECK: atomicrmw and ptr {{.*}} seq_cst, align 471 (void) __sync_fetch_and_and (&sll, 1); // CHECK: atomicrmw and ptr {{.*}} seq_cst, align 872 (void) __sync_fetch_and_and (&ull, 1); // CHECK: atomicrmw and ptr {{.*}} seq_cst, align 873 74}75 76void test_fetch_and_op (void) // CHECK-LABEL: define{{.*}} void @test_fetch_and_op77{78 sc = __sync_fetch_and_add (&sc, 11); // CHECK: atomicrmw add79 uc = __sync_fetch_and_add (&uc, 11); // CHECK: atomicrmw add80 ss = __sync_fetch_and_add (&ss, 11); // CHECK: atomicrmw add81 us = __sync_fetch_and_add (&us, 11); // CHECK: atomicrmw add82 si = __sync_fetch_and_add (&si, 11); // CHECK: atomicrmw add83 ui = __sync_fetch_and_add (&ui, 11); // CHECK: atomicrmw add84 sll = __sync_fetch_and_add (&sll, 11); // CHECK: atomicrmw add85 ull = __sync_fetch_and_add (&ull, 11); // CHECK: atomicrmw add86 87 sc = __sync_fetch_and_sub (&sc, 11); // CHECK: atomicrmw sub88 uc = __sync_fetch_and_sub (&uc, 11); // CHECK: atomicrmw sub89 ss = __sync_fetch_and_sub (&ss, 11); // CHECK: atomicrmw sub90 us = __sync_fetch_and_sub (&us, 11); // CHECK: atomicrmw sub91 si = __sync_fetch_and_sub (&si, 11); // CHECK: atomicrmw sub92 ui = __sync_fetch_and_sub (&ui, 11); // CHECK: atomicrmw sub93 sll = __sync_fetch_and_sub (&sll, 11); // CHECK: atomicrmw sub94 ull = __sync_fetch_and_sub (&ull, 11); // CHECK: atomicrmw sub95 96 sc = __sync_fetch_and_or (&sc, 11); // CHECK: atomicrmw or97 uc = __sync_fetch_and_or (&uc, 11); // CHECK: atomicrmw or98 ss = __sync_fetch_and_or (&ss, 11); // CHECK: atomicrmw or99 us = __sync_fetch_and_or (&us, 11); // CHECK: atomicrmw or100 si = __sync_fetch_and_or (&si, 11); // CHECK: atomicrmw or101 ui = __sync_fetch_and_or (&ui, 11); // CHECK: atomicrmw or102 sll = __sync_fetch_and_or (&sll, 11); // CHECK: atomicrmw or103 ull = __sync_fetch_and_or (&ull, 11); // CHECK: atomicrmw or104 105 sc = __sync_fetch_and_xor (&sc, 11); // CHECK: atomicrmw xor106 uc = __sync_fetch_and_xor (&uc, 11); // CHECK: atomicrmw xor107 ss = __sync_fetch_and_xor (&ss, 11); // CHECK: atomicrmw xor108 us = __sync_fetch_and_xor (&us, 11); // CHECK: atomicrmw xor109 si = __sync_fetch_and_xor (&si, 11); // CHECK: atomicrmw xor110 ui = __sync_fetch_and_xor (&ui, 11); // CHECK: atomicrmw xor111 sll = __sync_fetch_and_xor (&sll, 11); // CHECK: atomicrmw xor112 ull = __sync_fetch_and_xor (&ull, 11); // CHECK: atomicrmw xor113 114 sc = __sync_fetch_and_nand (&sc, 11); // CHECK: atomicrmw nand115 uc = __sync_fetch_and_nand (&uc, 11); // CHECK: atomicrmw nand116 ss = __sync_fetch_and_nand (&ss, 11); // CHECK: atomicrmw nand117 us = __sync_fetch_and_nand (&us, 11); // CHECK: atomicrmw nand118 si = __sync_fetch_and_nand (&si, 11); // CHECK: atomicrmw nand119 ui = __sync_fetch_and_nand (&ui, 11); // CHECK: atomicrmw nand120 sll = __sync_fetch_and_nand (&sll, 11); // CHECK: atomicrmw nand121 ull = __sync_fetch_and_nand (&ull, 11); // CHECK: atomicrmw nand122 123 sc = __sync_fetch_and_and (&sc, 11); // CHECK: atomicrmw and124 uc = __sync_fetch_and_and (&uc, 11); // CHECK: atomicrmw and125 ss = __sync_fetch_and_and (&ss, 11); // CHECK: atomicrmw and126 us = __sync_fetch_and_and (&us, 11); // CHECK: atomicrmw and127 si = __sync_fetch_and_and (&si, 11); // CHECK: atomicrmw and128 ui = __sync_fetch_and_and (&ui, 11); // CHECK: atomicrmw and129 sll = __sync_fetch_and_and (&sll, 11); // CHECK: atomicrmw and130 ull = __sync_fetch_and_and (&ull, 11); // CHECK: atomicrmw and131 132}133 134void test_op_and_fetch (void)135{136 sc = __sync_add_and_fetch (&sc, uc); // CHECK: atomicrmw add137 uc = __sync_add_and_fetch (&uc, uc); // CHECK: atomicrmw add138 ss = __sync_add_and_fetch (&ss, uc); // CHECK: atomicrmw add139 us = __sync_add_and_fetch (&us, uc); // CHECK: atomicrmw add140 si = __sync_add_and_fetch (&si, uc); // CHECK: atomicrmw add141 ui = __sync_add_and_fetch (&ui, uc); // CHECK: atomicrmw add142 sll = __sync_add_and_fetch (&sll, uc); // CHECK: atomicrmw add143 ull = __sync_add_and_fetch (&ull, uc); // CHECK: atomicrmw add144 145 sc = __sync_sub_and_fetch (&sc, uc); // CHECK: atomicrmw sub146 uc = __sync_sub_and_fetch (&uc, uc); // CHECK: atomicrmw sub147 ss = __sync_sub_and_fetch (&ss, uc); // CHECK: atomicrmw sub148 us = __sync_sub_and_fetch (&us, uc); // CHECK: atomicrmw sub149 si = __sync_sub_and_fetch (&si, uc); // CHECK: atomicrmw sub150 ui = __sync_sub_and_fetch (&ui, uc); // CHECK: atomicrmw sub151 sll = __sync_sub_and_fetch (&sll, uc); // CHECK: atomicrmw sub152 ull = __sync_sub_and_fetch (&ull, uc); // CHECK: atomicrmw sub153 154 sc = __sync_or_and_fetch (&sc, uc); // CHECK: atomicrmw or155 uc = __sync_or_and_fetch (&uc, uc); // CHECK: atomicrmw or156 ss = __sync_or_and_fetch (&ss, uc); // CHECK: atomicrmw or157 us = __sync_or_and_fetch (&us, uc); // CHECK: atomicrmw or158 si = __sync_or_and_fetch (&si, uc); // CHECK: atomicrmw or159 ui = __sync_or_and_fetch (&ui, uc); // CHECK: atomicrmw or160 sll = __sync_or_and_fetch (&sll, uc); // CHECK: atomicrmw or161 ull = __sync_or_and_fetch (&ull, uc); // CHECK: atomicrmw or162 163 sc = __sync_xor_and_fetch (&sc, uc); // CHECK: atomicrmw xor164 uc = __sync_xor_and_fetch (&uc, uc); // CHECK: atomicrmw xor165 ss = __sync_xor_and_fetch (&ss, uc); // CHECK: atomicrmw xor166 us = __sync_xor_and_fetch (&us, uc); // CHECK: atomicrmw xor167 si = __sync_xor_and_fetch (&si, uc); // CHECK: atomicrmw xor168 ui = __sync_xor_and_fetch (&ui, uc); // CHECK: atomicrmw xor169 sll = __sync_xor_and_fetch (&sll, uc); // CHECK: atomicrmw xor170 ull = __sync_xor_and_fetch (&ull, uc); // CHECK: atomicrmw xor171 172 sc = __sync_nand_and_fetch (&sc, uc); // CHECK: atomicrmw nand173 // CHECK: and174 // CHECK: xor175 // CHECK: -1176 uc = __sync_nand_and_fetch (&uc, uc); // CHECK: atomicrmw nand177 // CHECK: and178 // CHECK: xor179 // CHECK: -1180 ss = __sync_nand_and_fetch (&ss, uc); // CHECK: atomicrmw nand181 // CHECK: and182 // CHECK: xor183 // CHECK: -1184 us = __sync_nand_and_fetch (&us, uc); // CHECK: atomicrmw nand185 // CHECK: and186 // CHECK: xor187 // CHECK: -1188 si = __sync_nand_and_fetch (&si, uc); // CHECK: atomicrmw nand189 // CHECK: and190 // CHECK: xor191 // CHECK: -1192 ui = __sync_nand_and_fetch (&ui, uc); // CHECK: atomicrmw nand193 // CHECK: and194 // CHECK: xor195 // CHECK: -1196 sll = __sync_nand_and_fetch (&sll, uc); // CHECK: atomicrmw nand197 // CHECK: and198 // CHECK: xor199 // CHECK: -1200 ull = __sync_nand_and_fetch (&ull, uc); // CHECK: atomicrmw nand201 // CHECK: and202 // CHECK: xor203 // CHECK: -1204 u128 = __sync_nand_and_fetch (&u128, uc); // CHECK: atomicrmw nand205 // CHECK: and206 // CHECK: xor207 // CHECK: -1208 s128 = __sync_nand_and_fetch (&s128, uc); // CHECK: atomicrmw nand209 // CHECK: and210 // CHECK: xor211 // CHECK: -1212 213 sc = __sync_and_and_fetch (&sc, uc); // CHECK: atomicrmw and214 uc = __sync_and_and_fetch (&uc, uc); // CHECK: atomicrmw and215 ss = __sync_and_and_fetch (&ss, uc); // CHECK: atomicrmw and216 us = __sync_and_and_fetch (&us, uc); // CHECK: atomicrmw and217 si = __sync_and_and_fetch (&si, uc); // CHECK: atomicrmw and218 ui = __sync_and_and_fetch (&ui, uc); // CHECK: atomicrmw and219 sll = __sync_and_and_fetch (&sll, uc); // CHECK: atomicrmw and220 ull = __sync_and_and_fetch (&ull, uc); // CHECK: atomicrmw and221 222}223 224void test_compare_and_swap (void)225{226 sc = __sync_val_compare_and_swap (&sc, uc, sc);227 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 1228 // CHECK: extractvalue { i8, i1 } [[PAIR]], 0229 230 uc = __sync_val_compare_and_swap (&uc, uc, sc);231 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 1232 // CHECK: extractvalue { i8, i1 } [[PAIR]], 0233 234 ss = __sync_val_compare_and_swap (&ss, uc, sc);235 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 2236 // CHECK: extractvalue { i16, i1 } [[PAIR]], 0237 238 us = __sync_val_compare_and_swap (&us, uc, sc);239 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 2240 // CHECK: extractvalue { i16, i1 } [[PAIR]], 0241 242 si = __sync_val_compare_and_swap (&si, uc, sc);243 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 4244 // CHECK: extractvalue { i32, i1 } [[PAIR]], 0245 246 ui = __sync_val_compare_and_swap (&ui, uc, sc);247 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 4248 // CHECK: extractvalue { i32, i1 } [[PAIR]], 0249 250 sll = __sync_val_compare_and_swap (&sll, uc, sc);251 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 8252 // CHECK: extractvalue { i64, i1 } [[PAIR]], 0253 254 ull = __sync_val_compare_and_swap (&ull, uc, sc);255 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 8256 // CHECK: extractvalue { i64, i1 } [[PAIR]], 0257 258 259 ui = __sync_bool_compare_and_swap (&sc, uc, sc);260 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 1261 // CHECK: extractvalue { i8, i1 } [[PAIR]], 1262 263 ui = __sync_bool_compare_and_swap (&uc, uc, sc);264 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 1265 // CHECK: extractvalue { i8, i1 } [[PAIR]], 1266 267 ui = __sync_bool_compare_and_swap (&ss, uc, sc);268 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 2269 // CHECK: extractvalue { i16, i1 } [[PAIR]], 1270 271 ui = __sync_bool_compare_and_swap (&us, uc, sc);272 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 2273 // CHECK: extractvalue { i16, i1 } [[PAIR]], 1274 275 ui = __sync_bool_compare_and_swap (&si, uc, sc);276 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 4277 // CHECK: extractvalue { i32, i1 } [[PAIR]], 1278 279 ui = __sync_bool_compare_and_swap (&ui, uc, sc);280 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 4281 // CHECK: extractvalue { i32, i1 } [[PAIR]], 1282 283 ui = __sync_bool_compare_and_swap (&sll, uc, sc);284 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 8285 // CHECK: extractvalue { i64, i1 } [[PAIR]], 1286 287 ui = __sync_bool_compare_and_swap (&ull, uc, sc);288 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 8289 // CHECK: extractvalue { i64, i1 } [[PAIR]], 1290}291 292void test_lock (void)293{294 sc = __sync_lock_test_and_set (&sc, 1); // CHECK: atomicrmw xchg ptr {{.*}} seq_cst, align 1295 uc = __sync_lock_test_and_set (&uc, 1); // CHECK: atomicrmw xchg ptr {{.*}} seq_cst, align 1296 ss = __sync_lock_test_and_set (&ss, 1); // CHECK: atomicrmw xchg ptr {{.*}} seq_cst, align 2297 us = __sync_lock_test_and_set (&us, 1); // CHECK: atomicrmw xchg ptr {{.*}} seq_cst, align 2298 si = __sync_lock_test_and_set (&si, 1); // CHECK: atomicrmw xchg ptr {{.*}} seq_cst, align 4299 ui = __sync_lock_test_and_set (&ui, 1); // CHECK: atomicrmw xchg ptr {{.*}} seq_cst, align 4300 sll = __sync_lock_test_and_set (&sll, 1); // CHECK: atomicrmw xchg ptr {{.*}} seq_cst, align 8301 ull = __sync_lock_test_and_set (&ull, 1); // CHECK: atomicrmw xchg ptr {{.*}} seq_cst, align 8302 303 __sync_synchronize (); // CHECK: fence seq_cst304 305 __sync_lock_release (&sc); // CHECK: store atomic {{.*}} release, align 1306 __sync_lock_release (&uc); // CHECK: store atomic {{.*}} release, align 1307 __sync_lock_release (&ss); // CHECK: store atomic {{.*}} release, align 2308 __sync_lock_release (&us); /// CHECK: store atomic {{.*}} release, align 2309 __sync_lock_release (&si); // CHECK: store atomic {{.*}} release, align 4310 __sync_lock_release (&ui); // CHECK: store atomic {{.*}} release, align 4311 __sync_lock_release (&sll); // CHECK: store atomic {{.*}} release, align 8312 __sync_lock_release (&ull); // CHECK: store atomic {{.*}} release, align 8313}314 315void test_atomic(void) {316 ui = __atomic_fetch_min(&ui, 5, __ATOMIC_RELAXED); // CHECK: atomicrmw umin {{.*}} monotonic, align 4317 si = __atomic_fetch_min(&si, 5, __ATOMIC_SEQ_CST); // CHECK: atomicrmw min {{.*}} seq_cst, align 4318 ui = __atomic_fetch_max(&ui, 5, __ATOMIC_ACQUIRE); // CHECK: atomicrmw umax {{.*}} acquire, align 4319 si = __atomic_fetch_max(&si, 5, __ATOMIC_RELEASE); // CHECK: atomicrmw max {{.*}} release, align 4320}321