blob: 9558dcde517c33ed581c5c2152b5e910c2825802 [file] [log] [blame]
Yaxun Liu39195062017-08-04 18:16:31 +00001// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -finclude-default-header -O0 -o - -triple=amdgcn-amd-amdhsa-opencl | FileCheck %s
2
3// Also test serialization of atomic operations here, to avoid duplicating the test.
4// RUN: %clang_cc1 %s -cl-std=CL2.0 -finclude-default-header -emit-pch -O0 -o %t -triple=amdgcn-amd-amdhsa-opencl
5// RUN: %clang_cc1 %s -cl-std=CL2.0 -finclude-default-header -include-pch %t -O0 -triple=amdgcn-amd-amdhsa-opencl -emit-llvm -o - | FileCheck %s
6
7#ifndef ALREADY_INCLUDED
8#define ALREADY_INCLUDED
9
10atomic_int j;
11
12void fi1(atomic_int *i) {
13 // CHECK-LABEL: @fi1
14 // CHECK: load atomic i32, i32 addrspace(4)* %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst
15 int x = __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_work_group);
16 // CHECK: load atomic i32, i32 addrspace(4)* %{{[.0-9A-Z_a-z]+}} syncscope("agent") seq_cst
17 x = __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_device);
18 // CHECK: load atomic i32, i32 addrspace(4)* %{{[.0-9A-Z_a-z]+}} seq_cst
19 x = __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_all_svm_devices);
20 // CHECK: load atomic i32, i32 addrspace(4)* %{{[.0-9A-Z_a-z]+}} syncscope("subgroup") seq_cst
21 x = __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_sub_group);
22}
23
24void fi2(atomic_int *i) {
25 // CHECK-LABEL: @fi2
26 // CHECK: store atomic i32 %{{[.0-9A-Z_a-z]+}}, i32 addrspace(4)* %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst
27 __opencl_atomic_store(i, 1, memory_order_seq_cst, memory_scope_work_group);
28}
29
30void fi3(atomic_int *i, atomic_uint *ui) {
31 // CHECK-LABEL: @fi3
32 // CHECK: atomicrmw and i32 addrspace(4)* %{{[.0-9A-Z_a-z]+}}, i32 %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst
33 int x = __opencl_atomic_fetch_and(i, 1, memory_order_seq_cst, memory_scope_work_group);
34 // CHECK: atomicrmw min i32 addrspace(4)* %{{[.0-9A-Z_a-z]+}}, i32 %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst
35 x = __opencl_atomic_fetch_min(i, 1, memory_order_seq_cst, memory_scope_work_group);
36 // CHECK: atomicrmw max i32 addrspace(4)* %{{[.0-9A-Z_a-z]+}}, i32 %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst
37 x = __opencl_atomic_fetch_max(i, 1, memory_order_seq_cst, memory_scope_work_group);
38 // CHECK: atomicrmw umin i32 addrspace(4)* %{{[.0-9A-Z_a-z]+}}, i32 %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst
39 x = __opencl_atomic_fetch_min(ui, 1, memory_order_seq_cst, memory_scope_work_group);
40 // CHECK: atomicrmw umax i32 addrspace(4)* %{{[.0-9A-Z_a-z]+}}, i32 %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst
41 x = __opencl_atomic_fetch_max(ui, 1, memory_order_seq_cst, memory_scope_work_group);
42}
43
44bool fi4(atomic_int *i) {
45 // CHECK-LABEL: @fi4(
46 // CHECK: [[PAIR:%[.0-9A-Z_a-z]+]] = cmpxchg i32 addrspace(4)* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]] syncscope("workgroup") acquire acquire
47 // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 0
48 // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 1
49 // CHECK: br i1 [[CMP]], label %[[STORE_EXPECTED:[.0-9A-Z_a-z]+]], label %[[CONTINUE:[.0-9A-Z_a-z]+]]
50 // CHECK: store i32 [[OLD]]
51 int cmp = 0;
52 return __opencl_atomic_compare_exchange_strong(i, &cmp, 1, memory_order_acquire, memory_order_acquire, memory_scope_work_group);
53}
54
55float ff1(global atomic_float *d) {
56 // CHECK-LABEL: @ff1
57 // CHECK: load atomic i32, i32 addrspace(1)* {{.*}} syncscope("workgroup") monotonic
58 return __opencl_atomic_load(d, memory_order_relaxed, memory_scope_work_group);
59}
60
61void ff2(atomic_float *d) {
62 // CHECK-LABEL: @ff2
63 // CHECK: store atomic i32 {{.*}} syncscope("workgroup") release
64 __opencl_atomic_store(d, 1, memory_order_release, memory_scope_work_group);
65}
66
67float ff3(atomic_float *d) {
68 // CHECK-LABEL: @ff3
69 // CHECK: atomicrmw xchg i32 addrspace(4)* {{.*}} syncscope("workgroup") seq_cst
70 return __opencl_atomic_exchange(d, 2, memory_order_seq_cst, memory_scope_work_group);
71}
72
73// CHECK-LABEL: @atomic_init_foo
74void atomic_init_foo()
75{
76 // CHECK-NOT: atomic
77 // CHECK: store
78 __opencl_atomic_init(&j, 42);
79
80 // CHECK-NOT: atomic
81 // CHECK: }
82}
83
84// CHECK-LABEL: @failureOrder
85void failureOrder(atomic_int *ptr, int *ptr2) {
86 // CHECK: cmpxchg i32 addrspace(4)* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} syncscope("workgroup") acquire monotonic
87 __opencl_atomic_compare_exchange_strong(ptr, ptr2, 43, memory_order_acquire, memory_order_relaxed, memory_scope_work_group);
88
89 // CHECK: cmpxchg weak i32 addrspace(4)* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} syncscope("workgroup") seq_cst acquire
90 __opencl_atomic_compare_exchange_weak(ptr, ptr2, 43, memory_order_seq_cst, memory_order_acquire, memory_scope_work_group);
91}
92
93// CHECK-LABEL: @generalFailureOrder
94void generalFailureOrder(atomic_int *ptr, int *ptr2, int success, int fail) {
95 __opencl_atomic_compare_exchange_strong(ptr, ptr2, 42, success, fail, memory_scope_work_group);
96 // CHECK: switch i32 {{.*}}, label %[[MONOTONIC:[0-9a-zA-Z._]+]] [
97 // CHECK-NEXT: i32 1, label %[[ACQUIRE:[0-9a-zA-Z._]+]]
98 // CHECK-NEXT: i32 2, label %[[ACQUIRE]]
99 // CHECK-NEXT: i32 3, label %[[RELEASE:[0-9a-zA-Z._]+]]
100 // CHECK-NEXT: i32 4, label %[[ACQREL:[0-9a-zA-Z._]+]]
101 // CHECK-NEXT: i32 5, label %[[SEQCST:[0-9a-zA-Z._]+]]
102
103 // CHECK: [[MONOTONIC]]
104 // CHECK: switch {{.*}}, label %[[MONOTONIC_MONOTONIC:[0-9a-zA-Z._]+]] [
105 // CHECK-NEXT: ]
106
107 // CHECK: [[ACQUIRE]]
108 // CHECK: switch {{.*}}, label %[[ACQUIRE_MONOTONIC:[0-9a-zA-Z._]+]] [
109 // CHECK-NEXT: i32 1, label %[[ACQUIRE_ACQUIRE:[0-9a-zA-Z._]+]]
110 // CHECK-NEXT: i32 2, label %[[ACQUIRE_ACQUIRE:[0-9a-zA-Z._]+]]
111 // CHECK-NEXT: ]
112
113 // CHECK: [[RELEASE]]
114 // CHECK: switch {{.*}}, label %[[RELEASE_MONOTONIC:[0-9a-zA-Z._]+]] [
115 // CHECK-NEXT: ]
116
117 // CHECK: [[ACQREL]]
118 // CHECK: switch {{.*}}, label %[[ACQREL_MONOTONIC:[0-9a-zA-Z._]+]] [
119 // CHECK-NEXT: i32 1, label %[[ACQREL_ACQUIRE:[0-9a-zA-Z._]+]]
120 // CHECK-NEXT: i32 2, label %[[ACQREL_ACQUIRE:[0-9a-zA-Z._]+]]
121 // CHECK-NEXT: ]
122
123 // CHECK: [[SEQCST]]
124 // CHECK: switch {{.*}}, label %[[SEQCST_MONOTONIC:[0-9a-zA-Z._]+]] [
125 // CHECK-NEXT: i32 1, label %[[SEQCST_ACQUIRE:[0-9a-zA-Z._]+]]
126 // CHECK-NEXT: i32 2, label %[[SEQCST_ACQUIRE:[0-9a-zA-Z._]+]]
127 // CHECK-NEXT: i32 5, label %[[SEQCST_SEQCST:[0-9a-zA-Z._]+]]
128 // CHECK-NEXT: ]
129
130 // CHECK: [[MONOTONIC_MONOTONIC]]
131 // CHECK: cmpxchg {{.*}} monotonic monotonic
132 // CHECK: br
133
134 // CHECK: [[ACQUIRE_MONOTONIC]]
135 // CHECK: cmpxchg {{.*}} acquire monotonic
136 // CHECK: br
137
138 // CHECK: [[ACQUIRE_ACQUIRE]]
139 // CHECK: cmpxchg {{.*}} acquire acquire
140 // CHECK: br
141
142 // CHECK: [[ACQREL_MONOTONIC]]
143 // CHECK: cmpxchg {{.*}} acq_rel monotonic
144 // CHECK: br
145
146 // CHECK: [[ACQREL_ACQUIRE]]
147 // CHECK: cmpxchg {{.*}} acq_rel acquire
148 // CHECK: br
149
150 // CHECK: [[SEQCST_MONOTONIC]]
151 // CHECK: cmpxchg {{.*}} seq_cst monotonic
152 // CHECK: br
153
154 // CHECK: [[SEQCST_ACQUIRE]]
155 // CHECK: cmpxchg {{.*}} seq_cst acquire
156 // CHECK: br
157
158 // CHECK: [[SEQCST_SEQCST]]
159 // CHECK: cmpxchg {{.*}} seq_cst seq_cst
160 // CHECK: br
161}
162
163int test_volatile(volatile atomic_int *i) {
164 // CHECK-LABEL: @test_volatile
165 // CHECK: %[[i_addr:.*]] = alloca i32
166 // CHECK-NEXT: %[[atomicdst:.*]] = alloca i32
167 // CHECK-NEXT: store i32 addrspace(4)* %i, i32 addrspace(4)** %[[i_addr]]
168 // CHECK-NEXT: %[[addr:.*]] = load i32 addrspace(4)*, i32 addrspace(4)** %[[i_addr]]
169 // CHECK-NEXT: %[[res:.*]] = load atomic volatile i32, i32 addrspace(4)* %[[addr]] syncscope("workgroup") seq_cst
170 // CHECK-NEXT: store i32 %[[res]], i32* %[[atomicdst]]
171 // CHECK-NEXT: %[[retval:.*]] = load i32, i32* %[[atomicdst]]
172 // CHECK-NEXT: ret i32 %[[retval]]
173 return __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_work_group);
174}
175
176#endif