brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.9 KiB · 7ef7720 Raw
321 lines · c
1// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-macosx10.9.0 | FileCheck %s2// REQUIRES: x86-registered-target3// Also test serialization of atomic operations here, to avoid duplicating the4// test.5// RUN: %clang_cc1 %s -emit-pch -o %t -triple=x86_64-apple-macosx10.9.06// RUN: %clang_cc1 %s -include-pch %t -triple=x86_64-apple-macosx10.9.0 -emit-llvm -o - | FileCheck %s7#ifndef ALREADY_INCLUDED8#define ALREADY_INCLUDED9 10// Basic IRGen tests for __c11_atomic_* and GNU __atomic_*11 12typedef enum memory_order {13  memory_order_relaxed, memory_order_consume, memory_order_acquire,14  memory_order_release, memory_order_acq_rel, memory_order_seq_cst15} memory_order;16 17int fi1(_Atomic(int) *i) {18  // CHECK: @fi119  // CHECK: load atomic i32, ptr {{.*}} seq_cst, align 420  return __c11_atomic_load(i, memory_order_seq_cst);21}22 23int fi1a(int *i) {24  // CHECK: @fi1a25  // CHECK: load atomic i32, ptr {{.*}} seq_cst, align 426  int v;27  __atomic_load(i, &v, memory_order_seq_cst);28  return v;29}30 31int fi1b(int *i) {32  // CHECK: @fi1b33  // CHECK: load atomic i32, ptr {{.*}} seq_cst, align 434  return __atomic_load_n(i, memory_order_seq_cst);35}36 37void fi2(_Atomic(int) *i) {38  // CHECK: @fi239  // CHECK: store atomic i32 {{.*}} seq_cst, align 440  __c11_atomic_store(i, 1, memory_order_seq_cst);41}42 43void fi2a(int *i) {44  // CHECK: @fi2a45  // CHECK: store atomic i32 {{.*}} seq_cst, align 446  int v = 1;47  __atomic_store(i, &v, memory_order_seq_cst);48}49 50void fi2b(int *i) {51  // CHECK: @fi2b52  // CHECK: store atomic i32 {{.*}} seq_cst, align 453  __atomic_store_n(i, 1, memory_order_seq_cst);54}55 56int fi3(_Atomic(int) *i) {57  // CHECK: @fi358  // CHECK: atomicrmw and {{.*}} seq_cst, align 459  // CHECK-NOT: and60  return __c11_atomic_fetch_and(i, 1, memory_order_seq_cst);61}62 63int fi3a(int *i) {64  // CHECK: @fi3a65  // CHECK: atomicrmw xor {{.*}} seq_cst, align 466  // CHECK-NOT: xor67  return __atomic_fetch_xor(i, 1, memory_order_seq_cst);68}69 70int fi3b(int *i) {71  // CHECK: @fi3b72  // CHECK: atomicrmw add {{.*}} seq_cst, align 473  // CHECK: add74  return __atomic_add_fetch(i, 1, memory_order_seq_cst);75}76 77int fi3c(int *i) {78  // CHECK: @fi3c79  // CHECK: atomicrmw nand {{.*}} seq_cst, align 480  // CHECK-NOT: and81  return __atomic_fetch_nand(i, 1, memory_order_seq_cst);82}83 84int fi3d(int *i) {85  // CHECK: @fi3d86  // CHECK: atomicrmw nand {{.*}} seq_cst, align 487  // CHECK: and88  // CHECK: xor89  return __atomic_nand_fetch(i, 1, memory_order_seq_cst);90}91 92_Bool fi4(_Atomic(int) *i) {93  // CHECK: @fi494  // CHECK: cmpxchg ptr {{.*}} acquire acquire, align 495  int cmp = 0;96  return __c11_atomic_compare_exchange_strong(i, &cmp, 1, memory_order_acquire, memory_order_acquire);97}98 99_Bool fi4a(int *i) {100  // CHECK: @fi4101  // CHECK: cmpxchg ptr {{.*}} acquire acquire, align 4102  int cmp = 0;103  int desired = 1;104  return __atomic_compare_exchange(i, &cmp, &desired, 0, memory_order_acquire, memory_order_acquire);105}106 107_Bool fi4b(int *i) {108  // CHECK: @fi4109  // CHECK: cmpxchg weak ptr {{.*}} acquire acquire, align 4110  int cmp = 0;111  return __atomic_compare_exchange_n(i, &cmp, 1, 1, memory_order_acquire, memory_order_acquire);112}113 114float ff1(_Atomic(float) *d) {115  // CHECK: @ff1116  // CHECK: load atomic i32, ptr {{.*}} monotonic, align 4117  return __c11_atomic_load(d, memory_order_relaxed);118}119 120void ff2(_Atomic(float) *d) {121  // CHECK: @ff2122  // CHECK: store atomic i32 {{.*}} release, align 4123  __c11_atomic_store(d, 1, memory_order_release);124}125 126float ff3(_Atomic(float) *d) {127  return __c11_atomic_exchange(d, 2, memory_order_seq_cst);128}129 130int* fp1(_Atomic(int*) *p) {131  // CHECK: @fp1132  // CHECK: load atomic i64, ptr {{.*}} seq_cst, align 8133  return __c11_atomic_load(p, memory_order_seq_cst);134}135 136int* fp2(_Atomic(int*) *p) {137  // CHECK: @fp2138  // CHECK: store i64 4139  // CHECK: atomicrmw add {{.*}} monotonic, align 8140  return __c11_atomic_fetch_add(p, 1, memory_order_relaxed);141}142 143int *fp2a(int **p) {144  // CHECK: @fp2a145  // CHECK: store i64 4146  // CHECK: atomicrmw sub {{.*}} monotonic, align 8147  // Note, the GNU builtins do not multiply by sizeof(T)!148  return __atomic_fetch_sub(p, 4, memory_order_relaxed);149}150 151_Complex float fc(_Atomic(_Complex float) *c) {152  // CHECK: @fc153  // CHECK: atomicrmw xchg ptr {{.*}} seq_cst, align 8154  return __c11_atomic_exchange(c, 2, memory_order_seq_cst);155}156 157typedef struct X { int x; } X;158X fs(_Atomic(X) *c) {159  // CHECK: @fs160  // CHECK: atomicrmw xchg ptr {{.*}} seq_cst, align 4161  return __c11_atomic_exchange(c, (X){2}, memory_order_seq_cst);162}163 164X fsa(X *c, X *d) {165  // CHECK: @fsa166  // CHECK: atomicrmw xchg ptr {{.*}} seq_cst, align 4167  X ret;168  __atomic_exchange(c, d, &ret, memory_order_seq_cst);169  return ret;170}171 172_Bool fsb(_Bool *c) {173  // CHECK: @fsb174  // CHECK: atomicrmw xchg ptr {{.*}} seq_cst, align 1175  return __atomic_exchange_n(c, 1, memory_order_seq_cst);176}177 178char flag1;179volatile char flag2;180void test_and_set(void) {181  // CHECK: atomicrmw xchg ptr @flag1, i8 1 seq_cst, align 1182  __atomic_test_and_set(&flag1, memory_order_seq_cst);183  // CHECK: atomicrmw volatile xchg ptr @flag2, i8 1 acquire, align 1184  __atomic_test_and_set(&flag2, memory_order_acquire);185  // CHECK: store atomic volatile i8 0, ptr @flag2 release, align 1186  __atomic_clear(&flag2, memory_order_release);187  // CHECK: store atomic i8 0, ptr @flag1 seq_cst, align 1188  __atomic_clear(&flag1, memory_order_seq_cst);189}190 191struct Sixteen {192  char c[16];193} sixteen;194struct Seventeen {195  char c[17];196} seventeen;197 198int lock_free(struct Incomplete *incomplete) {199  // CHECK: @lock_free200 201  // CHECK: call zeroext i1 @__atomic_is_lock_free(i64 noundef 3, ptr noundef null)202  __c11_atomic_is_lock_free(3);203 204  // CHECK: call zeroext i1 @__atomic_is_lock_free(i64 noundef 16, ptr noundef {{.*}}@sixteen{{.*}})205  __atomic_is_lock_free(16, &sixteen);206 207  // CHECK: call zeroext i1 @__atomic_is_lock_free(i64 noundef 17, ptr noundef {{.*}}@seventeen{{.*}})208  __atomic_is_lock_free(17, &seventeen);209 210  // CHECK: call zeroext i1 @__atomic_is_lock_free(i64 noundef 4, {{.*}})211  __atomic_is_lock_free(4, incomplete);212 213  char cs[20];214  // CHECK: call zeroext i1 @__atomic_is_lock_free(i64 noundef 4, {{.*}})215  __atomic_is_lock_free(4, cs+1);216 217  // CHECK-NOT: call218  __atomic_always_lock_free(3, 0);219  __atomic_always_lock_free(16, 0);220  __atomic_always_lock_free(17, 0);221  __atomic_always_lock_free(16, &sixteen);222  __atomic_always_lock_free(17, &seventeen);223 224  int n;225  __atomic_is_lock_free(4, &n);226 227  // CHECK: ret i32 1228  return __c11_atomic_is_lock_free(sizeof(_Atomic(int)));229}230 231// Tests for atomic operations on big values.  These should call the functions232// defined here:233// http://gcc.gnu.org/wiki/Atomic/GCCMM/LIbrary#The_Library_interface234 235struct foo {236  int big[128];237};238struct bar {239  char c[3];240};241 242struct bar smallThing, thing1, thing2;243struct foo bigThing;244_Atomic(struct foo) bigAtomic;245 246void structAtomicStore(void) {247  // CHECK: @structAtomicStore248  struct foo f = {0};249  __c11_atomic_store(&bigAtomic, f, 5);250  // CHECK: call void @__atomic_store(i64 noundef 512, ptr noundef @bigAtomic,251 252  struct bar b = {0};253  __atomic_store(&smallThing, &b, 5);254  // CHECK: call void @__atomic_store(i64 noundef 3, ptr noundef @smallThing255 256  __atomic_store(&bigThing, &f, 5);257  // CHECK: call void @__atomic_store(i64 noundef 512, ptr noundef @bigThing258}259void structAtomicLoad(void) {260  // CHECK: @structAtomicLoad261  struct foo f = __c11_atomic_load(&bigAtomic, 5);262  // CHECK: call void @__atomic_load(i64 noundef 512, ptr noundef @bigAtomic,263 264  struct bar b;265  __atomic_load(&smallThing, &b, 5);266  // CHECK: call void @__atomic_load(i64 noundef 3, ptr noundef @smallThing267 268  __atomic_load(&bigThing, &f, 5);269  // CHECK: call void @__atomic_load(i64 noundef 512, ptr noundef @bigThing270}271struct foo structAtomicExchange(void) {272  // CHECK: @structAtomicExchange273  struct foo f = {0};274  struct foo old;275  __atomic_exchange(&f, &bigThing, &old, 5);276  // CHECK: call void @__atomic_exchange(i64 noundef 512, {{.*}}, ptr noundef @bigThing,277 278  return __c11_atomic_exchange(&bigAtomic, f, 5);279  // CHECK: call void @__atomic_exchange(i64 noundef 512, ptr noundef @bigAtomic,280}281int structAtomicCmpExchange(void) {282  // CHECK: @structAtomicCmpExchange283  _Bool x = __atomic_compare_exchange(&smallThing, &thing1, &thing2, 1, 5, 5);284  // CHECK: call zeroext i1 @__atomic_compare_exchange(i64 noundef 3, {{.*}} @smallThing{{.*}} @thing1{{.*}} @thing2285 286  struct foo f = {0};287  struct foo g = {0};288  g.big[12] = 12;289  return x & __c11_atomic_compare_exchange_strong(&bigAtomic, &f, g, 5, 5);290  // CHECK: call zeroext i1 @__atomic_compare_exchange(i64 noundef 512, ptr noundef @bigAtomic,291}292 293// Check that no atomic operations are used in any initialisation of _Atomic294// types.295_Atomic(int) atomic_init_i = 42;296 297// CHECK: @atomic_init_foo298void atomic_init_foo(void)299{300  // CHECK-NOT: }301  // CHECK-NOT: atomic302  // CHECK: store303  _Atomic(int) j = 12;304 305  // CHECK-NOT: }306  // CHECK-NOT: atomic307  // CHECK: store308  __c11_atomic_init(&j, 42);309 310  // CHECK-NOT: atomic311  // CHECK: }312}313 314// Check this doesn't crash315// CHECK: @test_atomic_array_param(316void test_atomic_array_param(_Atomic(struct foo) a) {317  test_atomic_array_param(a);318}319 320#endif321