[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / CodeGen / scoped-fence-ops.c
blob376cb11e84d3da54e439ff7149bbcb1e6c84c63c
1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
2 // RUN: %clang_cc1 %s -emit-llvm -o - -triple=amdgcn-amd-amdhsa -ffreestanding \
3 // RUN: -fvisibility=hidden | FileCheck --check-prefix=AMDGCN %s
4 // RUN: %clang_cc1 %s -emit-llvm -o - -triple=spirv64-unknown-unknown -ffreestanding \
5 // RUN: -fvisibility=hidden | FileCheck --check-prefix=SPIRV %s
6 // RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-unknown-linux-gnu -ffreestanding \
7 // RUN: -fvisibility=hidden | FileCheck --check-prefix=X86_64 %s
9 // AMDGCN-LABEL: define hidden void @fe1a(
10 // AMDGCN-SAME: ) #[[ATTR0:[0-9]+]] {
11 // AMDGCN-NEXT: [[ENTRY:.*:]]
12 // AMDGCN-NEXT: fence syncscope("workgroup-one-as") release
13 // AMDGCN-NEXT: ret void
15 // SPIRV-LABEL: define hidden spir_func void @fe1a(
16 // SPIRV-SAME: ) #[[ATTR0:[0-9]+]] {
17 // SPIRV-NEXT: [[ENTRY:.*:]]
18 // SPIRV-NEXT: fence syncscope("workgroup") release
19 // SPIRV-NEXT: ret void
21 // X86_64-LABEL: define hidden void @fe1a(
22 // X86_64-SAME: ) #[[ATTR0:[0-9]+]] {
23 // X86_64-NEXT: [[ENTRY:.*:]]
24 // X86_64-NEXT: fence release
25 // X86_64-NEXT: ret void
27 void fe1a() {
28 __scoped_atomic_thread_fence(__ATOMIC_RELEASE, __MEMORY_SCOPE_WRKGRP);
31 // AMDGCN-LABEL: define hidden void @fe1b(
32 // AMDGCN-SAME: i32 noundef [[ORD:%.*]]) #[[ATTR0]] {
33 // AMDGCN-NEXT: [[ENTRY:.*:]]
34 // AMDGCN-NEXT: [[ORD_ADDR:%.*]] = alloca i32, align 4, addrspace(5)
35 // AMDGCN-NEXT: [[ORD_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[ORD_ADDR]] to ptr
36 // AMDGCN-NEXT: store i32 [[ORD]], ptr [[ORD_ADDR_ASCAST]], align 4
37 // AMDGCN-NEXT: [[TMP0:%.*]] = load i32, ptr [[ORD_ADDR_ASCAST]], align 4
38 // AMDGCN-NEXT: switch i32 [[TMP0]], label %[[ATOMIC_SCOPE_CONTINUE:.*]] [
39 // AMDGCN-NEXT: i32 1, label %[[ACQUIRE:.*]]
40 // AMDGCN-NEXT: i32 2, label %[[ACQUIRE]]
41 // AMDGCN-NEXT: i32 3, label %[[RELEASE:.*]]
42 // AMDGCN-NEXT: i32 4, label %[[ACQREL:.*]]
43 // AMDGCN-NEXT: i32 5, label %[[SEQCST:.*]]
44 // AMDGCN-NEXT: ]
45 // AMDGCN: [[ATOMIC_SCOPE_CONTINUE]]:
46 // AMDGCN-NEXT: ret void
47 // AMDGCN: [[ACQUIRE]]:
48 // AMDGCN-NEXT: fence syncscope("workgroup-one-as") acquire
49 // AMDGCN-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
50 // AMDGCN: [[RELEASE]]:
51 // AMDGCN-NEXT: fence syncscope("workgroup-one-as") release
52 // AMDGCN-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
53 // AMDGCN: [[ACQREL]]:
54 // AMDGCN-NEXT: fence syncscope("workgroup-one-as") acq_rel
55 // AMDGCN-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
56 // AMDGCN: [[SEQCST]]:
57 // AMDGCN-NEXT: fence syncscope("workgroup") seq_cst
58 // AMDGCN-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
60 // SPIRV-LABEL: define hidden spir_func void @fe1b(
61 // SPIRV-SAME: i32 noundef [[ORD:%.*]]) #[[ATTR0]] {
62 // SPIRV-NEXT: [[ENTRY:.*:]]
63 // SPIRV-NEXT: [[ORD_ADDR:%.*]] = alloca i32, align 4
64 // SPIRV-NEXT: store i32 [[ORD]], ptr [[ORD_ADDR]], align 4
65 // SPIRV-NEXT: [[TMP0:%.*]] = load i32, ptr [[ORD_ADDR]], align 4
66 // SPIRV-NEXT: switch i32 [[TMP0]], label %[[ATOMIC_SCOPE_CONTINUE:.*]] [
67 // SPIRV-NEXT: i32 1, label %[[ACQUIRE:.*]]
68 // SPIRV-NEXT: i32 2, label %[[ACQUIRE]]
69 // SPIRV-NEXT: i32 3, label %[[RELEASE:.*]]
70 // SPIRV-NEXT: i32 4, label %[[ACQREL:.*]]
71 // SPIRV-NEXT: i32 5, label %[[SEQCST:.*]]
72 // SPIRV-NEXT: ]
73 // SPIRV: [[ATOMIC_SCOPE_CONTINUE]]:
74 // SPIRV-NEXT: ret void
75 // SPIRV: [[ACQUIRE]]:
76 // SPIRV-NEXT: fence syncscope("workgroup") acquire
77 // SPIRV-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
78 // SPIRV: [[RELEASE]]:
79 // SPIRV-NEXT: fence syncscope("workgroup") release
80 // SPIRV-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
81 // SPIRV: [[ACQREL]]:
82 // SPIRV-NEXT: fence syncscope("workgroup") acq_rel
83 // SPIRV-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
84 // SPIRV: [[SEQCST]]:
85 // SPIRV-NEXT: fence syncscope("workgroup") seq_cst
86 // SPIRV-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
88 // X86_64-LABEL: define hidden void @fe1b(
89 // X86_64-SAME: i32 noundef [[ORD:%.*]]) #[[ATTR0]] {
90 // X86_64-NEXT: [[ENTRY:.*:]]
91 // X86_64-NEXT: [[ORD_ADDR:%.*]] = alloca i32, align 4
92 // X86_64-NEXT: store i32 [[ORD]], ptr [[ORD_ADDR]], align 4
93 // X86_64-NEXT: [[TMP0:%.*]] = load i32, ptr [[ORD_ADDR]], align 4
94 // X86_64-NEXT: switch i32 [[TMP0]], label %[[ATOMIC_SCOPE_CONTINUE:.*]] [
95 // X86_64-NEXT: i32 1, label %[[ACQUIRE:.*]]
96 // X86_64-NEXT: i32 2, label %[[ACQUIRE]]
97 // X86_64-NEXT: i32 3, label %[[RELEASE:.*]]
98 // X86_64-NEXT: i32 4, label %[[ACQREL:.*]]
99 // X86_64-NEXT: i32 5, label %[[SEQCST:.*]]
100 // X86_64-NEXT: ]
101 // X86_64: [[ATOMIC_SCOPE_CONTINUE]]:
102 // X86_64-NEXT: ret void
103 // X86_64: [[ACQUIRE]]:
104 // X86_64-NEXT: fence acquire
105 // X86_64-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
106 // X86_64: [[RELEASE]]:
107 // X86_64-NEXT: fence release
108 // X86_64-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
109 // X86_64: [[ACQREL]]:
110 // X86_64-NEXT: fence acq_rel
111 // X86_64-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
112 // X86_64: [[SEQCST]]:
113 // X86_64-NEXT: fence seq_cst
114 // X86_64-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
116 void fe1b(int ord) {
117 __scoped_atomic_thread_fence(ord, __MEMORY_SCOPE_WRKGRP);
120 // AMDGCN-LABEL: define hidden void @fe1c(
121 // AMDGCN-SAME: i32 noundef [[SCOPE:%.*]]) #[[ATTR0]] {
122 // AMDGCN-NEXT: [[ENTRY:.*:]]
123 // AMDGCN-NEXT: [[SCOPE_ADDR:%.*]] = alloca i32, align 4, addrspace(5)
124 // AMDGCN-NEXT: [[SCOPE_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[SCOPE_ADDR]] to ptr
125 // AMDGCN-NEXT: store i32 [[SCOPE]], ptr [[SCOPE_ADDR_ASCAST]], align 4
126 // AMDGCN-NEXT: [[TMP0:%.*]] = load i32, ptr [[SCOPE_ADDR_ASCAST]], align 4
127 // AMDGCN-NEXT: switch i32 [[TMP0]], label %[[ATOMIC_SCOPE_CONTINUE:.*]] [
128 // AMDGCN-NEXT: i32 1, label %[[DEVICE_SCOPE:.*]]
129 // AMDGCN-NEXT: i32 0, label %[[SYSTEM_SCOPE:.*]]
130 // AMDGCN-NEXT: i32 2, label %[[WORKGROUP_SCOPE:.*]]
131 // AMDGCN-NEXT: i32 3, label %[[WAVEFRONT_SCOPE:.*]]
132 // AMDGCN-NEXT: i32 4, label %[[SINGLE_SCOPE:.*]]
133 // AMDGCN-NEXT: ]
134 // AMDGCN: [[ATOMIC_SCOPE_CONTINUE]]:
135 // AMDGCN-NEXT: ret void
136 // AMDGCN: [[DEVICE_SCOPE]]:
137 // AMDGCN-NEXT: fence syncscope("agent-one-as") release
138 // AMDGCN-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
139 // AMDGCN: [[SYSTEM_SCOPE]]:
140 // AMDGCN-NEXT: fence syncscope("one-as") release
141 // AMDGCN-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
142 // AMDGCN: [[WORKGROUP_SCOPE]]:
143 // AMDGCN-NEXT: fence syncscope("workgroup-one-as") release
144 // AMDGCN-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
145 // AMDGCN: [[WAVEFRONT_SCOPE]]:
146 // AMDGCN-NEXT: fence syncscope("wavefront-one-as") release
147 // AMDGCN-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
148 // AMDGCN: [[SINGLE_SCOPE]]:
149 // AMDGCN-NEXT: fence syncscope("singlethread-one-as") release
150 // AMDGCN-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
152 // SPIRV-LABEL: define hidden spir_func void @fe1c(
153 // SPIRV-SAME: i32 noundef [[SCOPE:%.*]]) #[[ATTR0]] {
154 // SPIRV-NEXT: [[ENTRY:.*:]]
155 // SPIRV-NEXT: [[SCOPE_ADDR:%.*]] = alloca i32, align 4
156 // SPIRV-NEXT: store i32 [[SCOPE]], ptr [[SCOPE_ADDR]], align 4
157 // SPIRV-NEXT: [[TMP0:%.*]] = load i32, ptr [[SCOPE_ADDR]], align 4
158 // SPIRV-NEXT: switch i32 [[TMP0]], label %[[ATOMIC_SCOPE_CONTINUE:.*]] [
159 // SPIRV-NEXT: i32 1, label %[[DEVICE_SCOPE:.*]]
160 // SPIRV-NEXT: i32 0, label %[[SYSTEM_SCOPE:.*]]
161 // SPIRV-NEXT: i32 2, label %[[WORKGROUP_SCOPE:.*]]
162 // SPIRV-NEXT: i32 3, label %[[WAVEFRONT_SCOPE:.*]]
163 // SPIRV-NEXT: i32 4, label %[[SINGLE_SCOPE:.*]]
164 // SPIRV-NEXT: ]
165 // SPIRV: [[ATOMIC_SCOPE_CONTINUE]]:
166 // SPIRV-NEXT: ret void
167 // SPIRV: [[DEVICE_SCOPE]]:
168 // SPIRV-NEXT: fence syncscope("device") release
169 // SPIRV-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
170 // SPIRV: [[SYSTEM_SCOPE]]:
171 // SPIRV-NEXT: fence release
172 // SPIRV-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
173 // SPIRV: [[WORKGROUP_SCOPE]]:
174 // SPIRV-NEXT: fence syncscope("workgroup") release
175 // SPIRV-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
176 // SPIRV: [[WAVEFRONT_SCOPE]]:
177 // SPIRV-NEXT: fence syncscope("subgroup") release
178 // SPIRV-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
179 // SPIRV: [[SINGLE_SCOPE]]:
180 // SPIRV-NEXT: fence syncscope("singlethread") release
181 // SPIRV-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
183 // X86_64-LABEL: define hidden void @fe1c(
184 // X86_64-SAME: i32 noundef [[SCOPE:%.*]]) #[[ATTR0]] {
185 // X86_64-NEXT: [[ENTRY:.*:]]
186 // X86_64-NEXT: [[SCOPE_ADDR:%.*]] = alloca i32, align 4
187 // X86_64-NEXT: store i32 [[SCOPE]], ptr [[SCOPE_ADDR]], align 4
188 // X86_64-NEXT: [[TMP0:%.*]] = load i32, ptr [[SCOPE_ADDR]], align 4
189 // X86_64-NEXT: switch i32 [[TMP0]], label %[[ATOMIC_SCOPE_CONTINUE:.*]] [
190 // X86_64-NEXT: i32 1, label %[[DEVICE_SCOPE:.*]]
191 // X86_64-NEXT: i32 0, label %[[SYSTEM_SCOPE:.*]]
192 // X86_64-NEXT: i32 2, label %[[WORKGROUP_SCOPE:.*]]
193 // X86_64-NEXT: i32 3, label %[[WAVEFRONT_SCOPE:.*]]
194 // X86_64-NEXT: i32 4, label %[[SINGLE_SCOPE:.*]]
195 // X86_64-NEXT: ]
196 // X86_64: [[ATOMIC_SCOPE_CONTINUE]]:
197 // X86_64-NEXT: ret void
198 // X86_64: [[DEVICE_SCOPE]]:
199 // X86_64-NEXT: fence release
200 // X86_64-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
201 // X86_64: [[SYSTEM_SCOPE]]:
202 // X86_64-NEXT: fence release
203 // X86_64-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
204 // X86_64: [[WORKGROUP_SCOPE]]:
205 // X86_64-NEXT: fence release
206 // X86_64-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
207 // X86_64: [[WAVEFRONT_SCOPE]]:
208 // X86_64-NEXT: fence release
209 // X86_64-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
210 // X86_64: [[SINGLE_SCOPE]]:
211 // X86_64-NEXT: fence release
212 // X86_64-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]]
214 void fe1c(int scope) {
215 __scoped_atomic_thread_fence(__ATOMIC_RELEASE, scope);
218 // AMDGCN-LABEL: define hidden void @fe2a(
219 // AMDGCN-SAME: ) #[[ATTR0]] {
220 // AMDGCN-NEXT: [[ENTRY:.*:]]
221 // AMDGCN-NEXT: ret void
223 // SPIRV-LABEL: define hidden spir_func void @fe2a(
224 // SPIRV-SAME: ) #[[ATTR0]] {
225 // SPIRV-NEXT: [[ENTRY:.*:]]
226 // SPIRV-NEXT: ret void
228 // X86_64-LABEL: define hidden void @fe2a(
229 // X86_64-SAME: ) #[[ATTR0]] {
230 // X86_64-NEXT: [[ENTRY:.*:]]
231 // X86_64-NEXT: ret void
233 void fe2a() {
234 __scoped_atomic_thread_fence(999, __MEMORY_SCOPE_SYSTEM);
237 // AMDGCN-LABEL: define hidden void @fe2b(
238 // AMDGCN-SAME: ) #[[ATTR0]] {
239 // AMDGCN-NEXT: [[ENTRY:.*:]]
240 // AMDGCN-NEXT: fence syncscope("one-as") release
241 // AMDGCN-NEXT: ret void
243 // SPIRV-LABEL: define hidden spir_func void @fe2b(
244 // SPIRV-SAME: ) #[[ATTR0]] {
245 // SPIRV-NEXT: [[ENTRY:.*:]]
246 // SPIRV-NEXT: fence release
247 // SPIRV-NEXT: ret void
249 // X86_64-LABEL: define hidden void @fe2b(
250 // X86_64-SAME: ) #[[ATTR0]] {
251 // X86_64-NEXT: [[ENTRY:.*:]]
252 // X86_64-NEXT: fence release
253 // X86_64-NEXT: ret void
255 void fe2b() {
256 __scoped_atomic_thread_fence(__ATOMIC_RELEASE, 999);