1 // RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-apple-darwin9 | FileCheck %s 2 3 // Also test serialization of atomic operations here, to avoid duplicating the 4 // test. 5 // RUN: %clang_cc1 %s -emit-pch -o %t -triple=i686-apple-darwin9 6 // RUN: %clang_cc1 %s -include-pch %t -triple=i686-apple-darwin9 -emit-llvm -o - | FileCheck %s 7 #ifndef ALREADY_INCLUDED 8 #define ALREADY_INCLUDED 9 10 // Basic IRGen tests for __c11_atomic_* and GNU __atomic_* 11 12 typedef enum memory_order { 13 memory_order_relaxed, memory_order_consume, memory_order_acquire, 14 memory_order_release, memory_order_acq_rel, memory_order_seq_cst 15 } memory_order; 16 17 int fi1(_Atomic(int) *i) { 18 // CHECK: @fi1 19 // CHECK: load atomic i32* {{.*}} seq_cst 20 return __c11_atomic_load(i, memory_order_seq_cst); 21 } 22 23 int fi1a(int *i) { 24 // CHECK: @fi1a 25 // CHECK: load atomic i32* {{.*}} seq_cst 26 int v; 27 __atomic_load(i, &v, memory_order_seq_cst); 28 return v; 29 } 30 31 int fi1b(int *i) { 32 // CHECK: @fi1b 33 // CHECK: load atomic i32* {{.*}} seq_cst 34 return __atomic_load_n(i, memory_order_seq_cst); 35 } 36 37 void fi2(_Atomic(int) *i) { 38 // CHECK: @fi2 39 // CHECK: store atomic i32 {{.*}} seq_cst 40 __c11_atomic_store(i, 1, memory_order_seq_cst); 41 } 42 43 void fi2a(int *i) { 44 // CHECK: @fi2a 45 // CHECK: store atomic i32 {{.*}} seq_cst 46 int v = 1; 47 __atomic_store(i, &v, memory_order_seq_cst); 48 } 49 50 void fi2b(int *i) { 51 // CHECK: @fi2b 52 // CHECK: store atomic i32 {{.*}} seq_cst 53 __atomic_store_n(i, 1, memory_order_seq_cst); 54 } 55 56 int fi3(_Atomic(int) *i) { 57 // CHECK: @fi3 58 // CHECK: atomicrmw and 59 // CHECK-NOT: and 60 return __c11_atomic_fetch_and(i, 1, memory_order_seq_cst); 61 } 62 63 int fi3a(int *i) { 64 // CHECK: @fi3a 65 // CHECK: atomicrmw xor 66 // CHECK-NOT: xor 67 return __atomic_fetch_xor(i, 1, memory_order_seq_cst); 68 } 69 70 int fi3b(int *i) { 71 // CHECK: @fi3b 72 // CHECK: atomicrmw add 73 // CHECK: add 74 return __atomic_add_fetch(i, 1, memory_order_seq_cst); 75 } 76 77 int fi3c(int *i) { 78 // CHECK: @fi3c 79 // CHECK: atomicrmw nand 80 // CHECK-NOT: and 81 return __atomic_fetch_nand(i, 1, memory_order_seq_cst); 82 } 83 84 int fi3d(int *i) { 85 // CHECK: @fi3d 86 // CHECK: atomicrmw nand 87 // CHECK: and 88 // CHECK: xor 89 return __atomic_nand_fetch(i, 1, memory_order_seq_cst); 90 } 91 92 _Bool fi4(_Atomic(int) *i) { 93 // CHECK: @fi4 94 // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = cmpxchg i32* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]] 95 // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = icmp eq i32 [[OLD]], [[EXPECTED]] 96 // CHECK: br i1 [[CMP]], label %[[STORE_EXPECTED:[.0-9A-Z_a-z]+]], label %[[CONTINUE:[.0-9A-Z_a-z]+]] 97 // CHECK: store i32 [[OLD]] 98 int cmp = 0; 99 return __c11_atomic_compare_exchange_strong(i, &cmp, 1, memory_order_acquire, memory_order_acquire); 100 } 101 102 _Bool fi4a(int *i) { 103 // CHECK: @fi4 104 // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = cmpxchg i32* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]] 105 // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = icmp eq i32 [[OLD]], [[EXPECTED]] 106 // CHECK: br i1 [[CMP]], label %[[STORE_EXPECTED:[.0-9A-Z_a-z]+]], label %[[CONTINUE:[.0-9A-Z_a-z]+]] 107 // CHECK: store i32 [[OLD]] 108 int cmp = 0; 109 int desired = 1; 110 return __atomic_compare_exchange(i, &cmp, &desired, 0, memory_order_acquire, memory_order_acquire); 111 } 112 113 _Bool fi4b(int *i) { 114 // CHECK: @fi4 115 // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = cmpxchg i32* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]] 116 // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = icmp eq i32 [[OLD]], [[EXPECTED]] 117 // CHECK: br i1 [[CMP]], label %[[STORE_EXPECTED:[.0-9A-Z_a-z]+]], label %[[CONTINUE:[.0-9A-Z_a-z]+]] 118 // CHECK: store i32 [[OLD]] 119 int cmp = 0; 120 return __atomic_compare_exchange_n(i, &cmp, 1, 1, memory_order_acquire, memory_order_acquire); 121 } 122 123 float ff1(_Atomic(float) *d) { 124 // CHECK: @ff1 125 // CHECK: load atomic i32* {{.*}} monotonic 126 return __c11_atomic_load(d, memory_order_relaxed); 127 } 128 129 void ff2(_Atomic(float) *d) { 130 // CHECK: @ff2 131 // CHECK: store atomic i32 {{.*}} release 132 __c11_atomic_store(d, 1, memory_order_release); 133 } 134 135 float ff3(_Atomic(float) *d) { 136 return __c11_atomic_exchange(d, 2, memory_order_seq_cst); 137 } 138 139 int* fp1(_Atomic(int*) *p) { 140 // CHECK: @fp1 141 // CHECK: load atomic i32* {{.*}} seq_cst 142 return __c11_atomic_load(p, memory_order_seq_cst); 143 } 144 145 int* fp2(_Atomic(int*) *p) { 146 // CHECK: @fp2 147 // CHECK: store i32 4 148 // CHECK: atomicrmw add {{.*}} monotonic 149 return __c11_atomic_fetch_add(p, 1, memory_order_relaxed); 150 } 151 152 int *fp2a(int **p) { 153 // CHECK: @fp2a 154 // CHECK: store i32 4 155 // CHECK: atomicrmw sub {{.*}} monotonic 156 // Note, the GNU builtins do not multiply by sizeof(T)! 157 return __atomic_fetch_sub(p, 4, memory_order_relaxed); 158 } 159 160 _Complex float fc(_Atomic(_Complex float) *c) { 161 // CHECK: @fc 162 // CHECK: atomicrmw xchg i64* 163 return __c11_atomic_exchange(c, 2, memory_order_seq_cst); 164 } 165 166 typedef struct X { int x; } X; 167 X fs(_Atomic(X) *c) { 168 // CHECK: @fs 169 // CHECK: atomicrmw xchg i32* 170 return __c11_atomic_exchange(c, (X){2}, memory_order_seq_cst); 171 } 172 173 X fsa(X *c, X *d) { 174 // CHECK: @fsa 175 // CHECK: atomicrmw xchg i32* 176 X ret; 177 __atomic_exchange(c, d, &ret, memory_order_seq_cst); 178 return ret; 179 } 180 181 _Bool fsb(_Bool *c) { 182 // CHECK: @fsb 183 // CHECK: atomicrmw xchg i8* 184 return __atomic_exchange_n(c, 1, memory_order_seq_cst); 185 } 186 187 char flag1; 188 volatile char flag2; 189 void test_and_set() { 190 // CHECK: atomicrmw xchg i8* @flag1, i8 1 seq_cst 191 __atomic_test_and_set(&flag1, memory_order_seq_cst); 192 // CHECK: atomicrmw volatile xchg i8* @flag2, i8 1 acquire 193 __atomic_test_and_set(&flag2, memory_order_acquire); 194 // CHECK: store atomic volatile i8 0, i8* @flag2 release 195 __atomic_clear(&flag2, memory_order_release); 196 // CHECK: store atomic i8 0, i8* @flag1 seq_cst 197 __atomic_clear(&flag1, memory_order_seq_cst); 198 } 199 200 struct Sixteen { 201 char c[16]; 202 } sixteen; 203 struct Seventeen { 204 char c[17]; 205 } seventeen; 206 207 int lock_free(struct Incomplete *incomplete) { 208 // CHECK: @lock_free 209 210 // CHECK: call i32 @__atomic_is_lock_free(i32 3, i8* null) 211 __c11_atomic_is_lock_free(3); 212 213 // CHECK: call i32 @__atomic_is_lock_free(i32 16, i8* {{.*}}@sixteen{{.*}}) 214 __atomic_is_lock_free(16, &sixteen); 215 216 // CHECK: call i32 @__atomic_is_lock_free(i32 17, i8* {{.*}}@seventeen{{.*}}) 217 __atomic_is_lock_free(17, &seventeen); 218 219 // CHECK: call i32 @__atomic_is_lock_free(i32 4, {{.*}}) 220 __atomic_is_lock_free(4, incomplete); 221 222 char cs[20]; 223 // CHECK: call i32 @__atomic_is_lock_free(i32 4, {{.*}}) 224 __atomic_is_lock_free(4, cs+1); 225 226 // CHECK-NOT: call 227 __atomic_always_lock_free(3, 0); 228 __atomic_always_lock_free(16, 0); 229 __atomic_always_lock_free(17, 0); 230 __atomic_always_lock_free(16, &sixteen); 231 __atomic_always_lock_free(17, &seventeen); 232 233 int n; 234 __atomic_is_lock_free(4, &n); 235 236 // CHECK: ret i32 1 237 return __c11_atomic_is_lock_free(sizeof(_Atomic(int))); 238 } 239 240 // Tests for atomic operations on big values. These should call the functions 241 // defined here: 242 // http://gcc.gnu.org/wiki/Atomic/GCCMM/LIbrary#The_Library_interface 243 244 struct foo { 245 int big[128]; 246 }; 247 struct bar { 248 char c[3]; 249 }; 250 251 struct bar smallThing, thing1, thing2; 252 struct foo bigThing; 253 _Atomic(struct foo) bigAtomic; 254 255 void structAtomicStore() { 256 // CHECK: @structAtomicStore 257 struct foo f = {0}; 258 struct bar b = {0}; 259 __atomic_store(&smallThing, &b, 5); 260 // CHECK: call void @__atomic_store(i32 3, i8* {{.*}} @smallThing 261 262 __atomic_store(&bigThing, &f, 5); 263 // CHECK: call void @__atomic_store(i32 512, i8* {{.*}} @bigThing 264 } 265 void structAtomicLoad() { 266 // CHECK: @structAtomicLoad 267 struct bar b; 268 __atomic_load(&smallThing, &b, 5); 269 // CHECK: call void @__atomic_load(i32 3, i8* {{.*}} @smallThing 270 271 struct foo f = {0}; 272 __atomic_load(&bigThing, &f, 5); 273 // CHECK: call void @__atomic_load(i32 512, i8* {{.*}} @bigThing 274 } 275 struct foo structAtomicExchange() { 276 // CHECK: @structAtomicExchange 277 struct foo f = {0}; 278 struct foo old; 279 __atomic_exchange(&f, &bigThing, &old, 5); 280 // CHECK: call void @__atomic_exchange(i32 512, {{.*}}, i8* bitcast ({{.*}} @bigThing to i8*), 281 282 return __c11_atomic_exchange(&bigAtomic, f, 5); 283 // CHECK: call void @__atomic_exchange(i32 512, i8* bitcast ({{.*}} @bigAtomic to i8*), 284 } 285 int structAtomicCmpExchange() { 286 // CHECK: @structAtomicCmpExchange 287 _Bool x = __atomic_compare_exchange(&smallThing, &thing1, &thing2, 1, 5, 5); 288 // CHECK: call zeroext i1 @__atomic_compare_exchange(i32 3, {{.*}} @smallThing{{.*}} @thing1{{.*}} @thing2 289 290 struct foo f = {0}; 291 struct foo g = {0}; 292 g.big[12] = 12; 293 return x & __c11_atomic_compare_exchange_strong(&bigAtomic, &f, g, 5, 5); 294 // CHECK: call zeroext i1 @__atomic_compare_exchange(i32 512, i8* bitcast ({{.*}} @bigAtomic to i8*), 295 } 296 297 // Check that no atomic operations are used in any initialisation of _Atomic 298 // types. 299 _Atomic(int) atomic_init_i = 42; 300 301 // CHECK: @atomic_init_foo 302 void atomic_init_foo() 303 { 304 // CHECK-NOT: } 305 // CHECK-NOT: atomic 306 // CHECK: store 307 _Atomic(int) j = 12; 308 309 // CHECK-NOT: } 310 // CHECK-NOT: atomic 311 // CHECK: store 312 __c11_atomic_init(&j, 42); 313 314 // CHECK-NOT: atomic 315 // CHECK: } 316 } 317 318 // CHECK-LABEL: @failureOrder 319 void failureOrder(_Atomic(int) *ptr, int *ptr2) { 320 __c11_atomic_compare_exchange_strong(ptr, ptr2, 43, memory_order_acquire, memory_order_relaxed); 321 // CHECK: cmpxchg i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} acquire monotonic 322 323 __c11_atomic_compare_exchange_weak(ptr, ptr2, 43, memory_order_seq_cst, memory_order_acquire); 324 // CHECK: cmpxchg i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} seq_cst acquire 325 326 // Unknown ordering: conservatively pick strongest valid option (for now!). 327 __atomic_compare_exchange(ptr2, ptr2, ptr2, 0, memory_order_acq_rel, *ptr2); 328 // CHECK: cmpxchg i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} acq_rel acquire 329 330 // Undefined behaviour: don't really care what that last ordering is so leave 331 // it out: 332 __atomic_compare_exchange_n(ptr2, ptr2, 43, 1, memory_order_seq_cst, 42); 333 // CHECK: cmpxchg i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} seq_cst 334 } 335 336 // CHECK-LABEL: @generalFailureOrder 337 void generalFailureOrder(_Atomic(int) *ptr, int *ptr2, int success, int fail) { 338 __c11_atomic_compare_exchange_strong(ptr, ptr2, 42, success, fail); 339 // CHECK: switch i32 {{.*}}, label %[[MONOTONIC:[0-9a-zA-Z._]+]] [ 340 // CHECK-NEXT: i32 1, label %[[ACQUIRE:[0-9a-zA-Z._]+]] 341 // CHECK-NEXT: i32 2, label %[[ACQUIRE]] 342 // CHECK-NEXT: i32 3, label %[[RELEASE:[0-9a-zA-Z._]+]] 343 // CHECK-NEXT: i32 4, label %[[ACQREL:[0-9a-zA-Z._]+]] 344 // CHECK-NEXT: i32 5, label %[[SEQCST:[0-9a-zA-Z._]+]] 345 346 // CHECK: [[MONOTONIC]] 347 // CHECK: switch {{.*}}, label %[[MONOTONIC_MONOTONIC:[0-9a-zA-Z._]+]] [ 348 // CHECK-NEXT: ] 349 350 // CHECK: [[ACQUIRE]] 351 // CHECK: switch {{.*}}, label %[[ACQUIRE_MONOTONIC:[0-9a-zA-Z._]+]] [ 352 // CHECK-NEXT: i32 1, label %[[ACQUIRE_ACQUIRE:[0-9a-zA-Z._]+]] 353 // CHECK-NEXT: i32 2, label %[[ACQUIRE_ACQUIRE:[0-9a-zA-Z._]+]] 354 // CHECK-NEXT: ] 355 356 // CHECK: [[RELEASE]] 357 // CHECK: switch {{.*}}, label %[[RELEASE_MONOTONIC:[0-9a-zA-Z._]+]] [ 358 // CHECK-NEXT: ] 359 360 // CHECK: [[ACQREL]] 361 // CHECK: switch {{.*}}, label %[[ACQREL_MONOTONIC:[0-9a-zA-Z._]+]] [ 362 // CHECK-NEXT: i32 1, label %[[ACQREL_ACQUIRE:[0-9a-zA-Z._]+]] 363 // CHECK-NEXT: i32 2, label %[[ACQREL_ACQUIRE:[0-9a-zA-Z._]+]] 364 // CHECK-NEXT: ] 365 366 // CHECK: [[SEQCST]] 367 // CHECK: switch {{.*}}, label %[[SEQCST_MONOTONIC:[0-9a-zA-Z._]+]] [ 368 // CHECK-NEXT: i32 1, label %[[SEQCST_ACQUIRE:[0-9a-zA-Z._]+]] 369 // CHECK-NEXT: i32 2, label %[[SEQCST_ACQUIRE:[0-9a-zA-Z._]+]] 370 // CHECK-NEXT: i32 5, label %[[SEQCST_SEQCST:[0-9a-zA-Z._]+]] 371 // CHECK-NEXT: ] 372 373 // CHECK: [[MONOTONIC_MONOTONIC]] 374 // CHECK: cmpxchg {{.*}} monotonic monotonic 375 // CHECK: br 376 377 // CHECK: [[ACQUIRE_MONOTONIC]] 378 // CHECK: cmpxchg {{.*}} acquire monotonic 379 // CHECK: br 380 381 // CHECK: [[ACQUIRE_ACQUIRE]] 382 // CHECK: cmpxchg {{.*}} acquire acquire 383 // CHECK: br 384 385 // CHECK: [[ACQREL_MONOTONIC]] 386 // CHECK: cmpxchg {{.*}} acq_rel monotonic 387 // CHECK: br 388 389 // CHECK: [[ACQREL_ACQUIRE]] 390 // CHECK: cmpxchg {{.*}} acq_rel acquire 391 // CHECK: br 392 393 // CHECK: [[SEQCST_MONOTONIC]] 394 // CHECK: cmpxchg {{.*}} seq_cst monotonic 395 // CHECK: br 396 397 // CHECK: [[SEQCST_ACQUIRE]] 398 // CHECK: cmpxchg {{.*}} seq_cst acquire 399 // CHECK: br 400 401 // CHECK: [[SEQCST_SEQCST]] 402 // CHECK: cmpxchg {{.*}} seq_cst seq_cst 403 // CHECK: br 404 } 405 406 #endif 407