blob: 287089d7c45e4d944644bfe3120fac883f663d06 [file] [log] [blame]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +00001// Test target codegen - host bc file has to be created first.
Samuel Antao1168d63c2016-06-30 21:22:08 +00002// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
3// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
4// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc
5// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
Alexey Bataev5e87c342016-12-22 19:44:05 +00006// RUN: %clang_cc1 -verify -fopenmp -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +00007// expected-no-diagnostics
8#ifndef HEADER
9#define HEADER
10
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +000011// CHECK-DAG: [[OMP_NT:@.+]] = common addrspace(3) global i32 0
12// CHECK-DAG: [[OMP_WID:@.+]] = common addrspace(3) global i64 0
13
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +000014template<typename tx, typename ty>
15struct TT{
16 tx X;
17 ty Y;
18};
19
20int foo(int n) {
21 int a = 0;
22 short aa = 0;
23 float b[10];
24 float bn[n];
25 double c[5][10];
26 double cn[5][n];
27 TT<long long, char> d;
28
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +000029 // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+foo.+l87}}_worker()
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +000030 // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
31 //
32 // CHECK: [[AWAIT_WORK]]
33 // CHECK: call void @llvm.nvvm.barrier0()
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +000034 // CHECK: [[WORK:%.+]] = load i64, i64 addrspace(3)* [[OMP_WID]],
35 // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i64 [[WORK]], 0
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +000036 // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
37 //
38 // CHECK: [[SEL_WORKERS]]
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +000039 // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
40 // CHECK: [[NT:%.+]] = load i32, i32 addrspace(3)* [[OMP_NT]]
41 // CHECK: [[IS_ACTIVE:%.+]] = icmp slt i32 [[TID]], [[NT]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +000042 // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]]
43 //
44 // CHECK: [[EXEC_PARALLEL]]
45 // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]]
46 //
47 // CHECK: [[TERM_PARALLEL]]
48 // CHECK: br label {{%?}}[[BAR_PARALLEL]]
49 //
50 // CHECK: [[BAR_PARALLEL]]
51 // CHECK: call void @llvm.nvvm.barrier0()
52 // CHECK: br label {{%?}}[[AWAIT_WORK]]
53 //
54 // CHECK: [[EXIT]]
55 // CHECK: ret void
56
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +000057 // CHECK: define {{.*}}void [[T1:@__omp_offloading_.+foo.+l87]]()
58 // CHECK: [[NTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
59 // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
60 // CHECK: [[A:%.+]] = sub i32 [[WS]], 1
61 // CHECK: [[B:%.+]] = sub i32 [[NTID]], 1
62 // CHECK: [[MID:%.+]] = and i32 [[B]],
63 // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
64 // CHECK: [[EXCESS:%.+]] = icmp ugt i32 [[TID]], [[MID]]
65 // CHECK: br i1 [[EXCESS]], label {{%?}}[[EXIT:.+]], label {{%?}}[[CHECK_WORKER:.+]]
66 //
67 // CHECK: [[CHECK_WORKER]]
68 // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[MID]]
69 // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[MASTER:.+]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +000070 //
71 // CHECK: [[WORKER]]
Alexey Bataev5e87c342016-12-22 19:44:05 +000072 // CHECK: {{call|invoke}} void [[T1]]_worker()
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +000073 // CHECK: br label {{%?}}[[EXIT]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +000074 //
75 // CHECK: [[MASTER]]
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +000076 // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
77 // CHECK: call void @__kmpc_kernel_init(i32 0, i32 [[TID]])
78 // CHECK: br label {{%?}}[[TERM:.+]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +000079 //
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +000080 // CHECK: [[TERM]]
81 // CHECK: store i64 0, i64 addrspace(3)* [[OMP_WID]],
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +000082 // CHECK: call void @llvm.nvvm.barrier0()
83 // CHECK: br label {{%?}}[[EXIT]]
84 //
85 // CHECK: [[EXIT]]
86 // CHECK: ret void
87 #pragma omp target
88 {
89 }
90
91 // CHECK-NOT: define {{.*}}void [[T2:@__omp_offloading_.+foo.+]]_worker()
92 #pragma omp target if(0)
93 {
94 }
95
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +000096 // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+foo.+l158}}_worker()
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +000097 // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
98 //
99 // CHECK: [[AWAIT_WORK]]
100 // CHECK: call void @llvm.nvvm.barrier0()
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000101 // CHECK: [[WORK:%.+]] = load i64, i64 addrspace(3)* [[OMP_WID]],
102 // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i64 [[WORK]], 0
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000103 // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
104 //
105 // CHECK: [[SEL_WORKERS]]
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000106 // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
107 // CHECK: [[NT:%.+]] = load i32, i32 addrspace(3)* [[OMP_NT]]
108 // CHECK: [[IS_ACTIVE:%.+]] = icmp slt i32 [[TID]], [[NT]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000109 // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]]
110 //
111 // CHECK: [[EXEC_PARALLEL]]
112 // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]]
113 //
114 // CHECK: [[TERM_PARALLEL]]
115 // CHECK: br label {{%?}}[[BAR_PARALLEL]]
116 //
117 // CHECK: [[BAR_PARALLEL]]
118 // CHECK: call void @llvm.nvvm.barrier0()
119 // CHECK: br label {{%?}}[[AWAIT_WORK]]
120 //
121 // CHECK: [[EXIT]]
122 // CHECK: ret void
123
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000124 // CHECK: define {{.*}}void [[T3:@__omp_offloading_.+foo.+l158]](i[[SZ:32|64]] [[ARG1:%[^)]+]])
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000125 // CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]],
126 // CHECK: store i[[SZ]] [[ARG1]], i[[SZ]]* [[AA_ADDR]],
127 // CHECK: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000128 // CHECK: [[NTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
129 // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
130 // CHECK: [[A:%.+]] = sub i32 [[WS]], 1
131 // CHECK: [[B:%.+]] = sub i32 [[NTID]], 1
132 // CHECK: [[MID:%.+]] = and i32 [[B]],
133 // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
134 // CHECK: [[EXCESS:%.+]] = icmp ugt i32 [[TID]], [[MID]]
135 // CHECK: br i1 [[EXCESS]], label {{%?}}[[EXIT:.+]], label {{%?}}[[CHECK_WORKER:.+]]
136 //
137 // CHECK: [[CHECK_WORKER]]
138 // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[MID]]
139 // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[MASTER:.+]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000140 //
141 // CHECK: [[WORKER]]
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000142 // CHECK: {{call|invoke}} void [[T3]]_worker()
143 // CHECK: br label {{%?}}[[EXIT]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000144 //
145 // CHECK: [[MASTER]]
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000146 // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
147 // CHECK: call void @__kmpc_kernel_init(i32 0, i32 [[TID]])
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000148 // CHECK: load i16, i16* [[AA_CADDR]],
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000149 // CHECK: br label {{%?}}[[TERM:.+]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000150 //
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000151 // CHECK: [[TERM]]
152 // CHECK: store i64 0, i64 addrspace(3)* [[OMP_WID]],
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000153 // CHECK: call void @llvm.nvvm.barrier0()
154 // CHECK: br label {{%?}}[[EXIT]]
155 //
156 // CHECK: [[EXIT]]
157 // CHECK: ret void
158 #pragma omp target if(1)
159 {
160 aa += 1;
161 }
162
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000163 // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+foo.+l261}}_worker()
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000164 // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
165 //
166 // CHECK: [[AWAIT_WORK]]
167 // CHECK: call void @llvm.nvvm.barrier0()
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000168 // CHECK: [[WORK:%.+]] = load i64, i64 addrspace(3)* [[OMP_WID]],
169 // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i64 [[WORK]], 0
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000170 // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
171 //
172 // CHECK: [[SEL_WORKERS]]
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000173 // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
174 // CHECK: [[NT:%.+]] = load i32, i32 addrspace(3)* [[OMP_NT]]
175 // CHECK: [[IS_ACTIVE:%.+]] = icmp slt i32 [[TID]], [[NT]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000176 // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]]
177 //
178 // CHECK: [[EXEC_PARALLEL]]
179 // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]]
180 //
181 // CHECK: [[TERM_PARALLEL]]
182 // CHECK: br label {{%?}}[[BAR_PARALLEL]]
183 //
184 // CHECK: [[BAR_PARALLEL]]
185 // CHECK: call void @llvm.nvvm.barrier0()
186 // CHECK: br label {{%?}}[[AWAIT_WORK]]
187 //
188 // CHECK: [[EXIT]]
189 // CHECK: ret void
190
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000191 // CHECK: define {{.*}}void [[T4:@__omp_offloading_.+foo.+l261]](i[[SZ]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000192 // Create local storage for each capture.
193 // CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
194 // CHECK: [[LOCAL_B:%.+]] = alloca [10 x float]*
195 // CHECK: [[LOCAL_VLA1:%.+]] = alloca i[[SZ]]
196 // CHECK: [[LOCAL_BN:%.+]] = alloca float*
197 // CHECK: [[LOCAL_C:%.+]] = alloca [5 x [10 x double]]*
198 // CHECK: [[LOCAL_VLA2:%.+]] = alloca i[[SZ]]
199 // CHECK: [[LOCAL_VLA3:%.+]] = alloca i[[SZ]]
200 // CHECK: [[LOCAL_CN:%.+]] = alloca double*
201 // CHECK: [[LOCAL_D:%.+]] = alloca [[TT:%.+]]*
202 // CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
203 // CHECK-DAG: store [10 x float]* [[ARG_B:%.+]], [10 x float]** [[LOCAL_B]]
204 // CHECK-DAG: store i[[SZ]] [[ARG_VLA1:%.+]], i[[SZ]]* [[LOCAL_VLA1]]
205 // CHECK-DAG: store float* [[ARG_BN:%.+]], float** [[LOCAL_BN]]
206 // CHECK-DAG: store [5 x [10 x double]]* [[ARG_C:%.+]], [5 x [10 x double]]** [[LOCAL_C]]
207 // CHECK-DAG: store i[[SZ]] [[ARG_VLA2:%.+]], i[[SZ]]* [[LOCAL_VLA2]]
208 // CHECK-DAG: store i[[SZ]] [[ARG_VLA3:%.+]], i[[SZ]]* [[LOCAL_VLA3]]
209 // CHECK-DAG: store double* [[ARG_CN:%.+]], double** [[LOCAL_CN]]
210 // CHECK-DAG: store [[TT]]* [[ARG_D:%.+]], [[TT]]** [[LOCAL_D]]
211 //
212 // CHECK-64-DAG: [[REF_A:%.+]] = bitcast i64* [[LOCAL_A]] to i32*
213 // CHECK-DAG: [[REF_B:%.+]] = load [10 x float]*, [10 x float]** [[LOCAL_B]],
214 // CHECK-DAG: [[VAL_VLA1:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA1]],
215 // CHECK-DAG: [[REF_BN:%.+]] = load float*, float** [[LOCAL_BN]],
216 // CHECK-DAG: [[REF_C:%.+]] = load [5 x [10 x double]]*, [5 x [10 x double]]** [[LOCAL_C]],
217 // CHECK-DAG: [[VAL_VLA2:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA2]],
218 // CHECK-DAG: [[VAL_VLA3:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA3]],
219 // CHECK-DAG: [[REF_CN:%.+]] = load double*, double** [[LOCAL_CN]],
220 // CHECK-DAG: [[REF_D:%.+]] = load [[TT]]*, [[TT]]** [[LOCAL_D]],
221 //
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000222 // CHECK: [[NTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
223 // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
224 // CHECK: [[A:%.+]] = sub i32 [[WS]], 1
225 // CHECK: [[B:%.+]] = sub i32 [[NTID]], 1
226 // CHECK: [[MID:%.+]] = and i32 [[B]],
227 // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
228 // CHECK: [[EXCESS:%.+]] = icmp ugt i32 [[TID]], [[MID]]
229 // CHECK: br i1 [[EXCESS]], label {{%?}}[[EXIT:.+]], label {{%?}}[[CHECK_WORKER:.+]]
230 //
231 // CHECK: [[CHECK_WORKER]]
232 // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[MID]]
233 // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[MASTER:.+]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000234 //
235 // CHECK: [[WORKER]]
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000236 // CHECK: {{call|invoke}} void [[T4]]_worker()
237 // CHECK: br label {{%?}}[[EXIT]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000238 //
239 // CHECK: [[MASTER]]
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000240 // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
241 // CHECK: call void @__kmpc_kernel_init(i32 0, i32 [[TID]])
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000242 //
243 // Use captures.
244 // CHECK-64-DAG: load i32, i32* [[REF_A]]
245 // CHECK-32-DAG: load i32, i32* [[LOCAL_A]]
246 // CHECK-DAG: getelementptr inbounds [10 x float], [10 x float]* [[REF_B]], i[[SZ]] 0, i[[SZ]] 2
247 // CHECK-DAG: getelementptr inbounds float, float* [[REF_BN]], i[[SZ]] 3
248 // CHECK-DAG: getelementptr inbounds [5 x [10 x double]], [5 x [10 x double]]* [[REF_C]], i[[SZ]] 0, i[[SZ]] 1
249 // CHECK-DAG: getelementptr inbounds double, double* [[REF_CN]], i[[SZ]] %{{.+}}
250 // CHECK-DAG: getelementptr inbounds [[TT]], [[TT]]* [[REF_D]], i32 0, i32 0
251 //
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000252 // CHECK: br label {{%?}}[[TERM:.+]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000253 //
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000254 // CHECK: [[TERM]]
255 // CHECK: store i64 0, i64 addrspace(3)* [[OMP_WID]],
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000256 // CHECK: call void @llvm.nvvm.barrier0()
257 // CHECK: br label {{%?}}[[EXIT]]
258 //
259 // CHECK: [[EXIT]]
260 // CHECK: ret void
261 #pragma omp target if(n>20)
262 {
263 a += 1;
264 b[2] += 1.0;
265 bn[3] += 1.0;
266 c[1][2] += 1.0;
267 cn[1][3] += 1.0;
268 d.X += 1;
269 d.Y += 1;
270 }
271
272 return a;
273}
274
275template<typename tx>
276tx ftemplate(int n) {
277 tx a = 0;
278 short aa = 0;
279 tx b[10];
280
281 #pragma omp target if(n>40)
282 {
283 a += 1;
284 aa += 1;
285 b[2] += 1;
286 }
287
288 return a;
289}
290
291static
292int fstatic(int n) {
293 int a = 0;
294 short aa = 0;
295 char aaa = 0;
296 int b[10];
297
298 #pragma omp target if(n>50)
299 {
300 a += 1;
301 aa += 1;
302 aaa += 1;
303 b[2] += 1;
304 }
305
306 return a;
307}
308
309struct S1 {
310 double a;
311
312 int r1(int n){
313 int b = n+1;
314 short int c[2][n];
315
316 #pragma omp target if(n>60)
317 {
318 this->a = (double)b + 1.5;
319 c[1][1] = ++a;
320 }
321
322 return c[1][1] + (int)b;
323 }
324};
325
326int bar(int n){
327 int a = 0;
328
329 a += foo(n);
330
331 S1 S;
332 a += S.r1(n);
333
334 a += fstatic(n);
335
336 a += ftemplate<int>(n);
337
338 return a;
339}
340
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000341 // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+static.+l298}}_worker()
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000342 // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
343 //
344 // CHECK: [[AWAIT_WORK]]
345 // CHECK: call void @llvm.nvvm.barrier0()
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000346 // CHECK: [[WORK:%.+]] = load i64, i64 addrspace(3)* [[OMP_WID]],
347 // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i64 [[WORK]], 0
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000348 // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
349 //
350 // CHECK: [[SEL_WORKERS]]
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000351 // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
352 // CHECK: [[NT:%.+]] = load i32, i32 addrspace(3)* [[OMP_NT]]
353 // CHECK: [[IS_ACTIVE:%.+]] = icmp slt i32 [[TID]], [[NT]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000354 // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]]
355 //
356 // CHECK: [[EXEC_PARALLEL]]
357 // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]]
358 //
359 // CHECK: [[TERM_PARALLEL]]
360 // CHECK: br label {{%?}}[[BAR_PARALLEL]]
361 //
362 // CHECK: [[BAR_PARALLEL]]
363 // CHECK: call void @llvm.nvvm.barrier0()
364 // CHECK: br label {{%?}}[[AWAIT_WORK]]
365 //
366 // CHECK: [[EXIT]]
367 // CHECK: ret void
368
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000369 // CHECK: define {{.*}}void [[T5:@__omp_offloading_.+static.+l298]](i[[SZ]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000370 // Create local storage for each capture.
371 // CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
372 // CHECK: [[LOCAL_AA:%.+]] = alloca i[[SZ]]
373 // CHECK: [[LOCAL_AAA:%.+]] = alloca i[[SZ]]
374 // CHECK: [[LOCAL_B:%.+]] = alloca [10 x i32]*
375 // CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
376 // CHECK-DAG: store i[[SZ]] [[ARG_AA:%.+]], i[[SZ]]* [[LOCAL_AA]]
377 // CHECK-DAG: store i[[SZ]] [[ARG_AAA:%.+]], i[[SZ]]* [[LOCAL_AAA]]
378 // CHECK-DAG: store [10 x i32]* [[ARG_B:%.+]], [10 x i32]** [[LOCAL_B]]
379 // Store captures in the context.
380 // CHECK-64-DAG: [[REF_A:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
381 // CHECK-DAG: [[REF_AA:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA]] to i16*
382 // CHECK-DAG: [[REF_AAA:%.+]] = bitcast i[[SZ]]* [[LOCAL_AAA]] to i8*
383 // CHECK-DAG: [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]],
384 //
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000385 // CHECK: [[NTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
386 // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
387 // CHECK: [[A:%.+]] = sub i32 [[WS]], 1
388 // CHECK: [[B:%.+]] = sub i32 [[NTID]], 1
389 // CHECK: [[MID:%.+]] = and i32 [[B]],
390 // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
391 // CHECK: [[EXCESS:%.+]] = icmp ugt i32 [[TID]], [[MID]]
392 // CHECK: br i1 [[EXCESS]], label {{%?}}[[EXIT:.+]], label {{%?}}[[CHECK_WORKER:.+]]
393 //
394 // CHECK: [[CHECK_WORKER]]
395 // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[MID]]
396 // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[MASTER:.+]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000397 //
398 // CHECK: [[WORKER]]
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000399 // CHECK: {{call|invoke}} void [[T5]]_worker()
400 // CHECK: br label {{%?}}[[EXIT]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000401 //
402 // CHECK: [[MASTER]]
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000403 // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
404 // CHECK: call void @__kmpc_kernel_init(i32 0, i32 [[TID]])
405 //
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000406 // CHECK-64-DAG: load i32, i32* [[REF_A]]
407 // CHECK-32-DAG: load i32, i32* [[LOCAL_A]]
408 // CHECK-DAG: load i16, i16* [[REF_AA]]
409 // CHECK-DAG: getelementptr inbounds [10 x i32], [10 x i32]* [[REF_B]], i[[SZ]] 0, i[[SZ]] 2
410 //
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000411 // CHECK: br label {{%?}}[[TERM:.+]]
412 //
413 // CHECK: [[TERM]]
414 // CHECK: store i64 0, i64 addrspace(3)* [[OMP_WID]],
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000415 // CHECK: call void @llvm.nvvm.barrier0()
416 // CHECK: br label {{%?}}[[EXIT]]
417 //
418 // CHECK: [[EXIT]]
419 // CHECK: ret void
420
421
422
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000423 // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+S1.+l316}}_worker()
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000424 // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
425 //
426 // CHECK: [[AWAIT_WORK]]
427 // CHECK: call void @llvm.nvvm.barrier0()
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000428 // CHECK: [[WORK:%.+]] = load i64, i64 addrspace(3)* [[OMP_WID]],
429 // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i64 [[WORK]], 0
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000430 // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
431 //
432 // CHECK: [[SEL_WORKERS]]
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000433 // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
434 // CHECK: [[NT:%.+]] = load i32, i32 addrspace(3)* [[OMP_NT]]
435 // CHECK: [[IS_ACTIVE:%.+]] = icmp slt i32 [[TID]], [[NT]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000436 // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]]
437 //
438 // CHECK: [[EXEC_PARALLEL]]
439 // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]]
440 //
441 // CHECK: [[TERM_PARALLEL]]
442 // CHECK: br label {{%?}}[[BAR_PARALLEL]]
443 //
444 // CHECK: [[BAR_PARALLEL]]
445 // CHECK: call void @llvm.nvvm.barrier0()
446 // CHECK: br label {{%?}}[[AWAIT_WORK]]
447 //
448 // CHECK: [[EXIT]]
449 // CHECK: ret void
450
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000451 // CHECK: define {{.*}}void [[T6:@__omp_offloading_.+S1.+l316]](
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000452 // Create local storage for each capture.
453 // CHECK: [[LOCAL_THIS:%.+]] = alloca [[S1:%struct.*]]*
454 // CHECK: [[LOCAL_B:%.+]] = alloca i[[SZ]]
455 // CHECK: [[LOCAL_VLA1:%.+]] = alloca i[[SZ]]
456 // CHECK: [[LOCAL_VLA2:%.+]] = alloca i[[SZ]]
457 // CHECK: [[LOCAL_C:%.+]] = alloca i16*
458 // CHECK-DAG: store [[S1]]* [[ARG_THIS:%.+]], [[S1]]** [[LOCAL_THIS]]
459 // CHECK-DAG: store i[[SZ]] [[ARG_B:%.+]], i[[SZ]]* [[LOCAL_B]]
460 // CHECK-DAG: store i[[SZ]] [[ARG_VLA1:%.+]], i[[SZ]]* [[LOCAL_VLA1]]
461 // CHECK-DAG: store i[[SZ]] [[ARG_VLA2:%.+]], i[[SZ]]* [[LOCAL_VLA2]]
462 // CHECK-DAG: store i16* [[ARG_C:%.+]], i16** [[LOCAL_C]]
463 // Store captures in the context.
464 // CHECK-DAG: [[REF_THIS:%.+]] = load [[S1]]*, [[S1]]** [[LOCAL_THIS]],
465 // CHECK-64-DAG:[[REF_B:%.+]] = bitcast i[[SZ]]* [[LOCAL_B]] to i32*
466 // CHECK-DAG: [[VAL_VLA1:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA1]],
467 // CHECK-DAG: [[VAL_VLA2:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA2]],
468 // CHECK-DAG: [[REF_C:%.+]] = load i16*, i16** [[LOCAL_C]],
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000469 // CHECK: [[NTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
470 // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
471 // CHECK: [[A:%.+]] = sub i32 [[WS]], 1
472 // CHECK: [[B:%.+]] = sub i32 [[NTID]], 1
473 // CHECK: [[MID:%.+]] = and i32 [[B]],
474 // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
475 // CHECK: [[EXCESS:%.+]] = icmp ugt i32 [[TID]], [[MID]]
476 // CHECK: br i1 [[EXCESS]], label {{%?}}[[EXIT:.+]], label {{%?}}[[CHECK_WORKER:.+]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000477 //
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000478 // CHECK: [[CHECK_WORKER]]
479 // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[MID]]
480 // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[MASTER:.+]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000481 //
482 // CHECK: [[WORKER]]
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000483 // CHECK: {{call|invoke}} void [[T6]]_worker()
484 // CHECK: br label {{%?}}[[EXIT]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000485 //
486 // CHECK: [[MASTER]]
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000487 // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
488 // CHECK: call void @__kmpc_kernel_init(i32 0, i32 [[TID]])
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000489 // Use captures.
490 // CHECK-DAG: getelementptr inbounds [[S1]], [[S1]]* [[REF_THIS]], i32 0, i32 0
491 // CHECK-64-DAG:load i32, i32* [[REF_B]]
492 // CHECK-32-DAG:load i32, i32* [[LOCAL_B]]
493 // CHECK-DAG: getelementptr inbounds i16, i16* [[REF_C]], i[[SZ]] %{{.+}}
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000494 // CHECK: br label {{%?}}[[TERM:.+]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000495 //
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000496 // CHECK: [[TERM]]
497 // CHECK: store i64 0, i64 addrspace(3)* [[OMP_WID]],
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000498 // CHECK: call void @llvm.nvvm.barrier0()
499 // CHECK: br label {{%?}}[[EXIT]]
500 //
501 // CHECK: [[EXIT]]
502 // CHECK: ret void
503
504
505
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000506 // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l281}}_worker()
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000507 // CHECK: br label {{%?}}[[AWAIT_WORK:.+]]
508 //
509 // CHECK: [[AWAIT_WORK]]
510 // CHECK: call void @llvm.nvvm.barrier0()
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000511 // CHECK: [[WORK:%.+]] = load i64, i64 addrspace(3)* [[OMP_WID]],
512 // CHECK: [[SHOULD_EXIT:%.+]] = icmp eq i64 [[WORK]], 0
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000513 // CHECK: br i1 [[SHOULD_EXIT]], label {{%?}}[[EXIT:.+]], label {{%?}}[[SEL_WORKERS:.+]]
514 //
515 // CHECK: [[SEL_WORKERS]]
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000516 // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
517 // CHECK: [[NT:%.+]] = load i32, i32 addrspace(3)* [[OMP_NT]]
518 // CHECK: [[IS_ACTIVE:%.+]] = icmp slt i32 [[TID]], [[NT]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000519 // CHECK: br i1 [[IS_ACTIVE]], label {{%?}}[[EXEC_PARALLEL:.+]], label {{%?}}[[BAR_PARALLEL:.+]]
520 //
521 // CHECK: [[EXEC_PARALLEL]]
522 // CHECK: br label {{%?}}[[TERM_PARALLEL:.+]]
523 //
524 // CHECK: [[TERM_PARALLEL]]
525 // CHECK: br label {{%?}}[[BAR_PARALLEL]]
526 //
527 // CHECK: [[BAR_PARALLEL]]
528 // CHECK: call void @llvm.nvvm.barrier0()
529 // CHECK: br label {{%?}}[[AWAIT_WORK]]
530 //
531 // CHECK: [[EXIT]]
532 // CHECK: ret void
533
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000534 // CHECK: define {{.*}}void [[T7:@__omp_offloading_.+template.+l281]](i[[SZ]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000535 // Create local storage for each capture.
536 // CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
537 // CHECK: [[LOCAL_AA:%.+]] = alloca i[[SZ]]
538 // CHECK: [[LOCAL_B:%.+]] = alloca [10 x i32]*
539 // CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
540 // CHECK-DAG: store i[[SZ]] [[ARG_AA:%.+]], i[[SZ]]* [[LOCAL_AA]]
541 // CHECK-DAG: store [10 x i32]* [[ARG_B:%.+]], [10 x i32]** [[LOCAL_B]]
542 // Store captures in the context.
543 // CHECK-64-DAG:[[REF_A:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
544 // CHECK-DAG: [[REF_AA:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA]] to i16*
545 // CHECK-DAG: [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]],
546 //
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000547 // CHECK: [[NTID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
548 // CHECK: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
549 // CHECK: [[A:%.+]] = sub i32 [[WS]], 1
550 // CHECK: [[B:%.+]] = sub i32 [[NTID]], 1
551 // CHECK: [[MID:%.+]] = and i32 [[B]],
552 // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
553 // CHECK: [[EXCESS:%.+]] = icmp ugt i32 [[TID]], [[MID]]
554 // CHECK: br i1 [[EXCESS]], label {{%?}}[[EXIT:.+]], label {{%?}}[[CHECK_WORKER:.+]]
555 //
556 // CHECK: [[CHECK_WORKER]]
557 // CHECK: [[IS_WORKER:%.+]] = icmp ult i32 [[TID]], [[MID]]
558 // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[MASTER:.+]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000559 //
560 // CHECK: [[WORKER]]
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000561 // CHECK: {{call|invoke}} void [[T7]]_worker()
562 // CHECK: br label {{%?}}[[EXIT]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000563 //
564 // CHECK: [[MASTER]]
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000565 // CHECK: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
566 // CHECK: call void @__kmpc_kernel_init(i32 0, i32 [[TID]])
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000567 //
568 // CHECK-64-DAG: load i32, i32* [[REF_A]]
569 // CHECK-32-DAG: load i32, i32* [[LOCAL_A]]
570 // CHECK-DAG: load i16, i16* [[REF_AA]]
571 // CHECK-DAG: getelementptr inbounds [10 x i32], [10 x i32]* [[REF_B]], i[[SZ]] 0, i[[SZ]] 2
572 //
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000573 // CHECK: br label {{%?}}[[TERM:.+]]
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000574 //
Arpith Chacko Jacobb0d96f52017-01-04 19:14:43 +0000575 // CHECK: [[TERM]]
576 // CHECK: store i64 0, i64 addrspace(3)* [[OMP_WID]],
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +0000577 // CHECK: call void @llvm.nvvm.barrier0()
578 // CHECK: br label {{%?}}[[EXIT]]
579 //
580 // CHECK: [[EXIT]]
581 // CHECK: ret void
582#endif