Clang Project

clang_source_code/test/OpenMP/target_codegen_global_capture.cpp
1// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
2// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
3// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
4// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
5// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
6// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
7
8// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
9// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
10// RUN: %clang_cc1 -fopenmp-simd -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s
11// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
12// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
13// RUN: %clang_cc1 -fopenmp-simd -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s
14// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
15// expected-no-diagnostics
16#ifndef HEADER
17#define HEADER
18
19
20// CHECK-DAG: [[GA:@.+]] = global double 1.000000e+00
21// CHECK-DAG: [[GB:@.+]] = global double 2.000000e+00
22// CHECK-DAG: [[GC:@.+]] = global double 3.000000e+00
23// CHECK-DAG: [[GD:@.+]] = global double 4.000000e+00
24// CHECK-DAG: [[FA:@.+]] = internal global float 5.000000e+00
25// CHECK-DAG: [[FB:@.+]] = internal global float 6.000000e+00
26// CHECK-DAG: [[FC:@.+]] = internal global float 7.000000e+00
27// CHECK-DAG: [[FD:@.+]] = internal global float 8.000000e+00
28// CHECK-DAG: [[BA:@.+]] = internal global float 9.000000e+00
29// CHECK-DAG: [[BB:@.+]] = internal global float 1.000000e+01
30// CHECK-DAG: [[BC:@.+]] = internal global float 1.100000e+01
31// CHECK-DAG: [[BD:@.+]] = internal global float 1.200000e+01
32// CHECK-DAG: [[TBA:@.+]] = {{.*}}global float 1.700000e+01
33// CHECK-DAG: [[TBB:@.+]] = {{.*}}global float 1.800000e+01
34// CHECK-DAG: [[TBC:@.+]] = {{.*}}global float 1.900000e+01
35// CHECK-DAG: [[TBD:@.+]] = {{.*}}global float 2.000000e+01
36
37double Ga = 1.0;
38double Gb = 2.0;
39double Gc = 3.0;
40double Gd = 4.0;
41
42// CHECK: define {{.*}} @{{.*}}foo{{.*}}(
43// CHECK-SAME: i16 {{[^,]*}}[[A:%[^,]+]],
44// CHECK-SAME: i16 {{[^,]*}}[[B:%[^,]+]],
45// CHECK-SAME: i16 {{[^,]*}}[[C:%[^,]+]],
46// CHECK-SAME: i16 {{[^,]*}}[[D:%[^,]+]])
47// CHECK: [[LA:%.+]] = alloca i16,
48// CHECK: [[LB:%.+]] = alloca i16,
49// CHECK: [[LC:%.+]] = alloca i16,
50// CHECK: [[LD:%.+]] = alloca i16,
51int foo(short a, short b, short c, short d){
52  static float Sa = 5.0;
53  static float Sb = 6.0;
54  static float Sc = 7.0;
55  static float Sd = 8.0;
56
57  // CHECK-DAG:    [[VALLB:%.+]] = load i16, i16* [[LB]],
58  // CHECK-64-DAG: [[VALGB:%.+]] = load double, double* [[GB]],
59  // CHECK-DAG:    [[VALFB:%.+]] = load float, float* [[FB]],
60  // CHECK-64-DAG: [[VALGC:%.+]] = load double, double* [[GC]],
61  // CHECK-DAG:    [[VALLC:%.+]] = load i16, i16* [[LC]],
62  // CHECK-DAG:    [[VALFC:%.+]] = load float, float* [[FC]],
63  // CHECK-DAG:    [[VALLD:%.+]] = load i16, i16* [[LD]],
64  // CHECK-64-DAG: [[VALGD:%.+]] = load double, double* [[GD]],
65  // CHECK-DAG:    [[VALFD:%.+]] = load float, float* [[FD]],
66
67  // 3 local vars being captured.
68
69  // CHECK-DAG: store i16 [[VALLB]], i16* [[CONVLB:%.+]],
70  // CHECK-DAG: [[CONVLB]] = bitcast i[[sz:64|32]]* [[CADDRLB:%.+]] to i16*
71  // CHECK-DAG: [[CVALLB:%.+]] = load i[[sz]], i[[sz]]* [[CADDRLB]],
72  // CHECK-DAG: store i[[sz]] [[CVALLB]], i[[sz]]* [[CBP:%.+]],
73  // CHECK-DAG: [[CBP]] = bitcast i8** [[GEPLB:%.+]] to i[[sz]]*
74  // CHECK-DAG: [[GEPLB]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
75
76  // CHECK-DAG: store i16 [[VALLC]], i16* [[CONVLC:%.+]],
77  // CHECK-DAG: [[CONVLC]] = bitcast i[[sz]]* [[CADDRLC:%.+]] to i16*
78  // CHECK-DAG: [[CVALLC:%.+]] = load i[[sz]], i[[sz]]* [[CADDRLC]],
79  // CHECK-DAG: store i[[sz]] [[CVALLC]], i[[sz]]* [[CBP:%.+]],
80  // CHECK-DAG: [[CBP]] = bitcast i8** [[GEPLC:%.+]] to i[[sz]]*
81  // CHECK-DAG: [[GEPLC]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
82
83  // CHECK-DAG: store i16 [[VALLD]], i16* [[CONVLD:%.+]],
84  // CHECK-DAG: [[CONVLD]] = bitcast i[[sz]]* [[CADDRLD:%.+]] to i16*
85  // CHECK-DAG: [[CVALLD:%.+]] = load i[[sz]], i[[sz]]* [[CADDRLD]],
86  // CHECK-DAG: store i[[sz]] [[CVALLD]], i[[sz]]* [[CBP:%.+]],
87  // CHECK-DAG: [[CBP]] = bitcast i8** [[GEPLD:%.+]] to i[[sz]]*
88  // CHECK-DAG: [[GEPLD]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
89
90  // 3 static vars being captured.
91
92  // CHECK-DAG: store float [[VALFB]], float* [[CONVFB:%.+]],
93  // CHECK-DAG: [[CONVFB]] = bitcast i[[sz]]* [[CADDRFB:%.+]] to float*
94  // CHECK-DAG: [[CVALFB:%.+]] = load i[[sz]], i[[sz]]* [[CADDRFB]],
95  // CHECK-DAG: store i[[sz]] [[CVALFB]], i[[sz]]* [[CBP:%.+]],
96  // CHECK-DAG: [[CBP]] = bitcast i8** [[GEPFB:%.+]] to i[[sz]]*
97  // CHECK-DAG: [[GEPFB]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
98
99  // CHECK-DAG: store float [[VALFC]], float* [[CONVFC:%.+]],
100  // CHECK-DAG: [[CONVFC]] = bitcast i[[sz]]* [[CADDRFC:%.+]] to float*
101  // CHECK-DAG: [[CVALFC:%.+]] = load i[[sz]], i[[sz]]* [[CADDRFC]],
102  // CHECK-DAG: store i[[sz]] [[CVALFC]], i[[sz]]* [[CBP:%.+]],
103  // CHECK-DAG: [[CBP]] = bitcast i8** [[GEPFC:%.+]] to i[[sz]]*
104  // CHECK-DAG: [[GEPFC]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
105
106  // CHECK-DAG: store float [[VALFD]], float* [[CONVFD:%.+]],
107  // CHECK-DAG: [[CONVFD]] = bitcast i[[sz]]* [[CADDRFD:%.+]] to float*
108  // CHECK-DAG: [[CVALFD:%.+]] = load i[[sz]], i[[sz]]* [[CADDRFD]],
109  // CHECK-DAG: store i[[sz]] [[CVALFD]], i[[sz]]* [[CBP:%.+]],
110  // CHECK-DAG: [[CBP]] = bitcast i8** [[GEPFD:%.+]] to i[[sz]]*
111  // CHECK-DAG: [[GEPFD]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
112
113  // 3 static global vars being captured.
114
115  // CHECK-64-DAG: store double [[VALGB]], double* [[CONVGB:%.+]],
116  // CHECK-64-DAG: [[CONVGB]] = bitcast i[[sz]]* [[CADDRGB:%.+]] to double*
117  // CHECK-64-DAG: [[CVALGB:%.+]] = load i[[sz]], i[[sz]]* [[CADDRGB]],
118  // CHECK-64-DAG: store i[[sz]] [[CVALGB]], i[[sz]]* [[CBP:%.+]],
119  // CHECK-64-DAG: [[CBP]] = bitcast i8** [[GEPGB:%.+]] to i[[sz]]*
120  // CHECK-32-DAG: store double* @Gb, double** [[CBP:%.+]],
121  // CHECK-32-DAG: [[CBP]] = bitcast i8** [[GEPGB:%.+]] to double**
122  // CHECK-DAG: [[GEPGB]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
123
124  // CHECK-64-DAG: store double [[VALGC]], double* [[CONVGC:%.+]],
125  // CHECK-64-DAG: [[CONVGC]] = bitcast i[[sz]]* [[CADDRGC:%.+]] to double*
126  // CHECK-64-DAG: [[CVALGC:%.+]] = load i[[sz]], i[[sz]]* [[CADDRGC]],
127  // CHECK-64-DAG: store i[[sz]] [[CVALGC]], i[[sz]]* [[CBP:%.+]],
128  // CHECK-64-DAG: [[CBP]] = bitcast i8** [[GEPGC:%.+]] to i[[sz]]*
129  // CHECK-32-DAG: store double* @Gc, double** [[CBP:%.+]],
130  // CHECK-32-DAG: [[CBP]] = bitcast i8** [[GEPGC:%.+]] to double**
131  // CHECK-DAG: [[GEPGC]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
132
133  // CHECK-64-DAG: store double [[VALGD]], double* [[CONVGD:%.+]],
134  // CHECK-64-DAG: [[CONVGD]] = bitcast i[[sz]]* [[CADDRGD:%.+]] to double*
135  // CHECK-64-DAG: [[CVALGD:%.+]] = load i[[sz]], i[[sz]]* [[CADDRGD]],
136  // CHECK-64-DAG: store i[[sz]] [[CVALGD]], i[[sz]]* [[CBP:%.+]],
137  // CHECK-64-DAG: [[CBP]] = bitcast i8** [[GEPGD:%.+]] to i[[sz]]*
138  // CHECK-32-DAG: store double* @Gd, double** [[CBP:%.+]],
139  // CHECK-32-DAG: [[CBP]] = bitcast i8** [[GEPGD:%.+]] to double**
140  // CHECK-DAG: [[GEPGD]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
141
142  // CHECK: call i32 @__tgt_target
143  // CHECK: call void [[OFFLOADF:@.+]](
144  // Capture b, Gb, Sb, Gc, c, Sc, d, Gd, Sd
145  #pragma omp target if(Ga>0.0 && a>0 && Sa>0.0)
146  {
147    b += 1;
148    Gb += 1.0;
149    Sb += 1.0;
150
151    // CHECK: define internal void [[OFFLOADF]]({{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}})
152    // The parallel region only uses 3 captures.
153    // CHECK:     call {{.*}}@__kmpc_fork_call(%struct.ident_t* {{.+}}, i32 {{.+}}, void (i32*, i32*, ...)* bitcast ({{.*}}[[PARF:@.+]] to {{.*}}), {{.+}}* %{{.+}}, {{.+}}* %{{.+}}, {{.+}}* %{{.+}})
154    // CHECK:     call void @.omp_outlined.(i32* %{{.+}}, i32* %{{.+}}, {{.+}}* %{{.+}}, {{.+}}* %{{.+}}, {{.+}}* %{{.+}})
155    // Capture d, Gd, Sd,
156
157    // CHECK: define internal void [[PARF]](i32* noalias %{{.*}}, i32* noalias %{{.*}},
158    #pragma omp parallel if(Gc>0.0 && c>0 && Sc>0.0)
159    {
160      d += 1;
161      Gd += 1.0;
162      Sd += 1.0;
163    }
164  }
165  return a + b + c + d + (int)Sa + (int)Sb + (int)Sc + (int)Sd;
166}
167
168// CHECK: define {{.*}} @{{.*}}bar{{.*}}(
169// CHECK-SAME: i16 {{[^,]*}}[[A:%[^,]+]],
170// CHECK-SAME: i16 {{[^,]*}}[[B:%[^,]+]],
171// CHECK-SAME: i16 {{[^,]*}}[[C:%[^,]+]],
172// CHECK-SAME: i16 {{[^,]*}}[[D:%[^,]+]])
173// CHECK: [[LA:%.+]] = alloca i16
174// CHECK: [[LB:%.+]] = alloca i16
175// CHECK: [[LC:%.+]] = alloca i16
176// CHECK: [[LD:%.+]] = alloca i16
177int bar(short a, short b, short c, short d){
178  static float Sa = 9.0;
179  static float Sb = 10.0;
180  static float Sc = 11.0;
181  static float Sd = 12.0;
182
183  // CHECK: call void {{.*}}@__kmpc_fork_call(%struct.ident_t* {{.+}}, i32 {{.+}}, void (i32*, i32*, ...)* bitcast ({{.*}}[[PARF:@.+]] to {{.*}}), i16* %{{.+}}, i16* %{{.+}}, i16* %{{.+}}, i16* %{{.+}})
184  // CHECK: define internal void [[PARF]](i32* noalias %{{.*}}, i32* noalias %{{.*}}, i16* dereferenceable(2) [[A:%.+]], i16* dereferenceable(2) [[B:%.+]], i16* dereferenceable(2) [[C:%.+]], i16* dereferenceable(2) [[D:%.+]])
185  // Capture a, b, c, d
186  // CHECK: [[ALLOCLA:%.+]] = alloca i16
187  // CHECK: [[ALLOCLB:%.+]] = alloca i16
188  // CHECK: [[ALLOCLC:%.+]] = alloca i16
189  // CHECK: [[ALLOCLD:%.+]] = alloca i16
190  // CHECK: [[LLA:%.+]] = load i16*, i16** [[ALLOCLA]],
191  // CHECK: [[LLB:%.+]] = load i16*, i16** [[ALLOCLB]],
192  // CHECK: [[LLC:%.+]] = load i16*, i16** [[ALLOCLC]],
193  // CHECK: [[LLD:%.+]] = load i16*, i16** [[ALLOCLD]],
194  #pragma omp parallel
195  {
196    // CHECK-DAG:    [[VALLB:%.+]] = load i16, i16* [[LLB]],
197    // CHECK-64-DAG: [[VALGB:%.+]] = load double, double* [[GB]],
198    // CHECK-DAG:    [[VALFB:%.+]] = load float, float* [[BB]],
199    // CHECK-64-DAG: [[VALGC:%.+]] = load double, double* [[GC]],
200    // CHECK-DAG:    [[VALLC:%.+]] = load i16, i16* [[LLC]],
201    // CHECK-DAG:    [[VALFC:%.+]] = load float, float* [[BC]],
202    // CHECK-DAG:    [[VALLD:%.+]] = load i16, i16* [[LLD]],
203    // CHECK-64-DAG: [[VALGD:%.+]] = load double, double* [[GD]],
204    // CHECK-DAG:    [[VALFD:%.+]] = load float, float* [[BD]],
205
206    // 3 local vars being captured.
207
208    // CHECK-DAG: store i16 [[VALLB]], i16* [[CONVLB:%.+]],
209    // CHECK-DAG: [[CONVLB]] = bitcast i[[sz:64|32]]* [[CADDRLB:%.+]] to i16*
210    // CHECK-DAG: [[CVALLB:%.+]] = load i[[sz]], i[[sz]]* [[CADDRLB]],
211    // CHECK-DAG: store i[[sz]] [[CVALLB]], i[[sz]]* [[CBP:%.+]],
212    // CHECK-DAG: [[CBP]] = bitcast i8** [[GEPLB:%.+]] to i[[sz]]*
213    // CHECK-DAG: [[GEPLB]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
214
215    // CHECK-DAG: store i16 [[VALLC]], i16* [[CONVLC:%.+]],
216    // CHECK-DAG: [[CONVLC]] = bitcast i[[sz]]* [[CADDRLC:%.+]] to i16*
217    // CHECK-DAG: [[CVALLC:%.+]] = load i[[sz]], i[[sz]]* [[CADDRLC]],
218    // CHECK-DAG: store i[[sz]] [[CVALLC]], i[[sz]]* [[CBP:%.+]],
219    // CHECK-DAG: [[CBP]] = bitcast i8** [[GEPLC:%.+]] to i[[sz]]*
220    // CHECK-DAG: [[GEPLC]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
221
222    // CHECK-DAG: store i16 [[VALLD]], i16* [[CONVLD:%.+]],
223    // CHECK-DAG: [[CONVLD]] = bitcast i[[sz]]* [[CADDRLD:%.+]] to i16*
224    // CHECK-DAG: [[CVALLD:%.+]] = load i[[sz]], i[[sz]]* [[CADDRLD]],
225    // CHECK-DAG: store i[[sz]] [[CVALLD]], i[[sz]]* [[CBP:%.+]],
226    // CHECK-DAG: [[CBP]] = bitcast i8** [[GEPLD:%.+]] to i[[sz]]*
227    // CHECK-DAG: [[GEPLD]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
228
229    // 3 static vars being captured.
230
231    // CHECK-DAG: store float [[VALFB]], float* [[CONVFB:%.+]],
232    // CHECK-DAG: [[CONVFB]] = bitcast i[[sz]]* [[CADDRFB:%.+]] to float*
233    // CHECK-DAG: [[CVALFB:%.+]] = load i[[sz]], i[[sz]]* [[CADDRFB]],
234    // CHECK-DAG: store i[[sz]] [[CVALFB]], i[[sz]]* [[CBP:%.+]],
235    // CHECK-DAG: [[CBP]] = bitcast i8** [[GEPFB:%.+]] to i[[sz]]*
236    // CHECK-DAG: [[GEPFB]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
237
238    // CHECK-DAG: store float [[VALFC]], float* [[CONVFC:%.+]],
239    // CHECK-DAG: [[CONVFC]] = bitcast i[[sz]]* [[CADDRFC:%.+]] to float*
240    // CHECK-DAG: [[CVALFC:%.+]] = load i[[sz]], i[[sz]]* [[CADDRFC]],
241    // CHECK-DAG: store i[[sz]] [[CVALFC]], i[[sz]]* [[CBP:%.+]],
242    // CHECK-DAG: [[CBP]] = bitcast i8** [[GEPFC:%.+]] to i[[sz]]*
243    // CHECK-DAG: [[GEPFC]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
244
245    // CHECK-DAG: store float [[VALFD]], float* [[CONVFD:%.+]],
246    // CHECK-DAG: [[CONVFD]] = bitcast i[[sz]]* [[CADDRFD:%.+]] to float*
247    // CHECK-DAG: [[CVALFD:%.+]] = load i[[sz]], i[[sz]]* [[CADDRFD]],
248    // CHECK-DAG: store i[[sz]] [[CVALFD]], i[[sz]]* [[CBP:%.+]],
249    // CHECK-DAG: [[CBP]] = bitcast i8** [[GEPFD:%.+]] to i[[sz]]*
250    // CHECK-DAG: [[GEPFD]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
251
252    // 3 static global vars being captured.
253
254    // CHECK-64-DAG: store double [[VALGB]], double* [[CONVGB:%.+]],
255    // CHECK-64-DAG: [[CONVGB]] = bitcast i[[sz]]* [[CADDRGB:%.+]] to double*
256    // CHECK-64-DAG: [[CVALGB:%.+]] = load i[[sz]], i[[sz]]* [[CADDRGB]],
257    // CHECK-64-DAG: store i[[sz]] [[CVALGB]], i[[sz]]* [[CBP:%.+]],
258    // CHECK-64-DAG: [[CBP]] = bitcast i8** [[GEPGB:%.+]] to i[[sz]]*
259    // CHECK-32-DAG: store double* @Gb, double** [[CBP:%.+]],
260    // CHECK-32-DAG: [[CBP]] = bitcast i8** [[GEPGB:%.+]] to double**
261    // CHECK-DAG: [[GEPGB]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
262
263    // CHECK-64-DAG: store double [[VALGC]], double* [[CONVGC:%.+]],
264    // CHECK-64-DAG: [[CONVGC]] = bitcast i[[sz]]* [[CADDRGC:%.+]] to double*
265    // CHECK-64-DAG: [[CVALGC:%.+]] = load i[[sz]], i[[sz]]* [[CADDRGC]],
266    // CHECK-64-DAG: store i[[sz]] [[CVALGC]], i[[sz]]* [[CBP:%.+]],
267    // CHECK-64-DAG: [[CBP]] = bitcast i8** [[GEPGC:%.+]] to i[[sz]]*
268    // CHECK-32-DAG: store double* @Gc, double** [[CBP:%.+]],
269    // CHECK-32-DAG: [[CBP]] = bitcast i8** [[GEPGC:%.+]] to double**
270    // CHECK-DAG: [[GEPGC]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
271
272    // CHECK-64-DAG: store double [[VALGD]], double* [[CONVGD:%.+]],
273    // CHECK-64-DAG: [[CONVGD]] = bitcast i[[sz]]* [[CADDRGD:%.+]] to double*
274    // CHECK-64-DAG: [[CVALGD:%.+]] = load i[[sz]], i[[sz]]* [[CADDRGD]],
275    // CHECK-64-DAG: store i[[sz]] [[CVALGD]], i[[sz]]* [[CBP:%.+]],
276    // CHECK-64-DAG: [[CBP]] = bitcast i8** [[GEPGD:%.+]] to i[[sz]]*
277    // CHECK-32-DAG: store double* @Gd, double** [[CBP:%.+]],
278    // CHECK-32-DAG: [[CBP]] = bitcast i8** [[GEPGD:%.+]] to double**
279    // CHECK-DAG: [[GEPGD]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
280
281    // CHECK: call i32 @__tgt_target
282    // CHECK: call void [[OFFLOADF:@.+]](
283    // Capture b, Gb, Sb, Gc, c, Sc, d, Gd, Sd
284    #pragma omp target if(Ga>0.0 && a>0 && Sa>0.0)
285    {
286      b += 1;
287      Gb += 1.0;
288      Sb += 1.0;
289
290      // CHECK: define internal void [[OFFLOADF]]({{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}})
291      // CHECK: call void {{.*}}@__kmpc_fork_call(%struct.ident_t* {{.+}}, i32 {{.+}}, void (i32*, i32*, ...)* bitcast ({{.*}}[[PARF:@.+]] to {{.*}})
292
293      // CHECK: define internal void [[PARF]](i32* noalias %{{.*}}, i32* noalias %{{.*}}, {{.+}}* dereferenceable({{.+}}) %{{.+}}, {{.+}}* dereferenceable({{.+}}) %{{.+}}, {{.+}}* dereferenceable({{.+}}) %{{.+}})
294      // Capture d, Gd, Sd
295      #pragma omp parallel if(Gc>0.0 && c>0 && Sc>0.0)
296      {
297        d += 1;
298        Gd += 1.0;
299        Sd += 1.0;
300      }
301    }
302  }
303  return a + b + c + d + (int)Sa + (int)Sb + (int)Sc + (int)Sd;
304}
305
306///
307/// Tests with template functions.
308///
309
310// CHECK: define {{.*}} @{{.*}}tbar2{{.*}}(
311
312// CHECK: define {{.*}} @{{.*}}tbar{{.*}}(
313// CHECK-SAME: i16 {{[^,]*}}[[A:%[^,]+]],
314// CHECK-SAME: i16 {{[^,]*}}[[B:%[^,]+]],
315// CHECK-SAME: i16 {{[^,]*}}[[C:%[^,]+]],
316// CHECK-SAME: i16 {{[^,]*}}[[D:%[^,]+]])
317// CHECK: [[LA:%.+]] = alloca i16
318// CHECK: [[LB:%.+]] = alloca i16
319// CHECK: [[LC:%.+]] = alloca i16
320// CHECK: [[LD:%.+]] = alloca i16
321template<typename T>
322int tbar(T a, T b, T c, T d){
323  static float Sa = 17.0;
324  static float Sb = 18.0;
325  static float Sc = 19.0;
326  static float Sd = 20.0;
327
328  // CHECK: call void {{.*}}@__kmpc_fork_call(%struct.ident_t* {{.+}}, i32 {{.+}}, void (i32*, i32*, ...)* bitcast ({{.*}}[[PARF:@.+]] to {{.*}}), i16* %{{.+}}, i16* %{{.+}}, i16* %{{.+}}, i16* %{{.+}})
329  // CHECK: define internal void [[PARF]](i32* noalias %{{.*}}, i32* noalias %{{.*}}, i16* dereferenceable(2) [[A:%.+]], i16* dereferenceable(2) [[B:%.+]], i16* dereferenceable(2) [[C:%.+]], i16* dereferenceable(2) [[D:%.+]])
330  // Capture a, b, c, d
331  // CHECK: [[ALLOCLA:%.+]] = alloca i16
332  // CHECK: [[ALLOCLB:%.+]] = alloca i16
333  // CHECK: [[ALLOCLC:%.+]] = alloca i16
334  // CHECK: [[ALLOCLD:%.+]] = alloca i16
335  // CHECK: [[LLA:%.+]] = load i16*, i16** [[ALLOCLA]],
336  // CHECK: [[LLB:%.+]] = load i16*, i16** [[ALLOCLB]],
337  // CHECK: [[LLC:%.+]] = load i16*, i16** [[ALLOCLC]],
338  // CHECK: [[LLD:%.+]] = load i16*, i16** [[ALLOCLD]],
339  #pragma omp parallel
340  {
341    // CHECK-DAG:    [[VALLB:%.+]] = load i16, i16* [[LLB]],
342    // CHECK-64-DAG: [[VALGB:%.+]] = load double, double* [[GB]],
343    // CHECK-DAG:    [[VALFB:%.+]] = load float, float* [[TBB]],
344    // CHECK-64-DAG: [[VALGC:%.+]] = load double, double* [[GC]],
345    // CHECK-DAG:    [[VALLC:%.+]] = load i16, i16* [[LLC]],
346    // CHECK-DAG:    [[VALFC:%.+]] = load float, float* [[TBC]],
347    // CHECK-DAG:    [[VALLD:%.+]] = load i16, i16* [[LLD]],
348    // CHECK-64-DAG: [[VALGD:%.+]] = load double, double* [[GD]],
349    // CHECK-DAG:    [[VALFD:%.+]] = load float, float* [[TBD]],
350
351    // 3 local vars being captured.
352
353    // CHECK-DAG: store i16 [[VALLB]], i16* [[CONVLB:%.+]],
354    // CHECK-DAG: [[CONVLB]] = bitcast i[[sz:64|32]]* [[CADDRLB:%.+]] to i16*
355    // CHECK-DAG: [[CVALLB:%.+]] = load i[[sz]], i[[sz]]* [[CADDRLB]],
356    // CHECK-DAG: store i[[sz]] [[CVALLB]], i[[sz]]* [[CBP:%.+]],
357    // CHECK-DAG: [[CBP]] = bitcast i8** [[GEPLB:%.+]] to i[[sz]]*
358    // CHECK-DAG: [[GEPLB]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
359
360    // CHECK-DAG: store i16 [[VALLC]], i16* [[CONVLC:%.+]],
361    // CHECK-DAG: [[CONVLC]] = bitcast i[[sz]]* [[CADDRLC:%.+]] to i16*
362    // CHECK-DAG: [[CVALLC:%.+]] = load i[[sz]], i[[sz]]* [[CADDRLC]],
363    // CHECK-DAG: store i[[sz]] [[CVALLC]], i[[sz]]* [[CBP:%.+]],
364    // CHECK-DAG: [[CBP]] = bitcast i8** [[GEPLC:%.+]] to i[[sz]]*
365    // CHECK-DAG: [[GEPLC]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
366
367    // CHECK-DAG: store i16 [[VALLD]], i16* [[CONVLD:%.+]],
368    // CHECK-DAG: [[CONVLD]] = bitcast i[[sz]]* [[CADDRLD:%.+]] to i16*
369    // CHECK-DAG: [[CVALLD:%.+]] = load i[[sz]], i[[sz]]* [[CADDRLD]],
370    // CHECK-DAG: store i[[sz]] [[CVALLD]], i[[sz]]* [[CBP:%.+]],
371    // CHECK-DAG: [[CBP]] = bitcast i8** [[GEPLD:%.+]] to i[[sz]]*
372    // CHECK-DAG: [[GEPLD]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
373
374    // 3 static vars being captured.
375
376    // CHECK-DAG: store float [[VALFB]], float* [[CONVFB:%.+]],
377    // CHECK-DAG: [[CONVFB]] = bitcast i[[sz]]* [[CADDRFB:%.+]] to float*
378    // CHECK-DAG: [[CVALFB:%.+]] = load i[[sz]], i[[sz]]* [[CADDRFB]],
379    // CHECK-DAG: store i[[sz]] [[CVALFB]], i[[sz]]* [[CBP:%.+]],
380    // CHECK-DAG: [[CBP]] = bitcast i8** [[GEPFB:%.+]] to i[[sz]]*
381    // CHECK-DAG: [[GEPFB]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
382
383    // CHECK-DAG: store float [[VALFC]], float* [[CONVFC:%.+]],
384    // CHECK-DAG: [[CONVFC]] = bitcast i[[sz]]* [[CADDRFC:%.+]] to float*
385    // CHECK-DAG: [[CVALFC:%.+]] = load i[[sz]], i[[sz]]* [[CADDRFC]],
386    // CHECK-DAG: store i[[sz]] [[CVALFC]], i[[sz]]* [[CBP:%.+]],
387    // CHECK-DAG: [[CBP]] = bitcast i8** [[GEPFC:%.+]] to i[[sz]]*
388    // CHECK-DAG: [[GEPFC]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
389
390    // CHECK-DAG: store float [[VALFD]], float* [[CONVFD:%.+]],
391    // CHECK-DAG: [[CONVFD]] = bitcast i[[sz]]* [[CADDRFD:%.+]] to float*
392    // CHECK-DAG: [[CVALFD:%.+]] = load i[[sz]], i[[sz]]* [[CADDRFD]],
393    // CHECK-DAG: store i[[sz]] [[CVALFD]], i[[sz]]* [[CBP:%.+]],
394    // CHECK-DAG: [[CBP]] = bitcast i8** [[GEPFD:%.+]] to i[[sz]]*
395    // CHECK-DAG: [[GEPFD]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
396
397    // 3 static global vars being captured.
398
399    // CHECK-64-DAG: store double [[VALGB]], double* [[CONVGB:%.+]],
400    // CHECK-64-DAG: [[CONVGB]] = bitcast i[[sz]]* [[CADDRGB:%.+]] to double*
401    // CHECK-64-DAG: [[CVALGB:%.+]] = load i[[sz]], i[[sz]]* [[CADDRGB]],
402    // CHECK-64-DAG: store i[[sz]] [[CVALGB]], i[[sz]]* [[CBP:%.+]],
403    // CHECK-64-DAG: [[CBP]] = bitcast i8** [[GEPGB:%.+]] to i[[sz]]*
404    // CHECK-32-DAG: store double* @Gb, double** [[CBP:%.+]],
405    // CHECK-32-DAG: [[CBP]] = bitcast i8** [[GEPGB:%.+]] to double**
406    // CHECK-DAG: [[GEPGB]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
407
408    // CHECK-64-DAG: store double [[VALGC]], double* [[CONVGC:%.+]],
409    // CHECK-64-DAG: [[CONVGC]] = bitcast i[[sz]]* [[CADDRGC:%.+]] to double*
410    // CHECK-64-DAG: [[CVALGC:%.+]] = load i[[sz]], i[[sz]]* [[CADDRGC]],
411    // CHECK-64-DAG: store i[[sz]] [[CVALGC]], i[[sz]]* [[CBP:%.+]],
412    // CHECK-64-DAG: [[CBP]] = bitcast i8** [[GEPGC:%.+]] to i[[sz]]*
413    // CHECK-32-DAG: store double* @Gc, double** [[CBP:%.+]],
414    // CHECK-32-DAG: [[CBP]] = bitcast i8** [[GEPGC:%.+]] to double**
415    // CHECK-DAG: [[GEPGC]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
416
417    // CHECK-64-DAG: store double [[VALGD]], double* [[CONVGD:%.+]],
418    // CHECK-64-DAG: [[CONVGD]] = bitcast i[[sz]]* [[CADDRGD:%.+]] to double*
419    // CHECK-64-DAG: [[CVALGD:%.+]] = load i[[sz]], i[[sz]]* [[CADDRGD]],
420    // CHECK-64-DAG: store i[[sz]] [[CVALGD]], i[[sz]]* [[CBP:%.+]],
421    // CHECK-64-DAG: [[CBP]] = bitcast i8** [[GEPGD:%.+]] to i[[sz]]*
422    // CHECK-32-DAG: store double* @Gd, double** [[CBP:%.+]],
423    // CHECK-32-DAG: [[CBP]] = bitcast i8** [[GEPGD:%.+]] to double**
424    // CHECK-DAG: [[GEPGD]] = getelementptr inbounds [9 x i8*], [9 x i8*]* %{{.+}}, i32 0, i32 {{[0-8]}}
425
426    // CHECK: call i32 @__tgt_target
427    // CHECK: call void [[OFFLOADF:@.+]](
428    // Capture b, Gb, Sb, Gc, c, Sc, d, Gd, Sd
429    #pragma omp target if(Ga>0.0 && a>0 && Sa>0.0)
430    {
431      b += 1;
432      Gb += 1.0;
433      Sb += 1.0;
434
435      // CHECK: define internal void [[OFFLOADF]]({{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}}, {{.+}} {{.*}}%{{.+}})
436      // CHECK: call void {{.*}}@__kmpc_fork_call(%struct.ident_t* {{.+}}, i32 {{.+}}, void (i32*, i32*, ...)* bitcast ({{.*}}[[PARF:@.+]] to {{.*}})
437
438      // CHECK: define internal void [[PARF]](i32* noalias %{{.*}}, i32* noalias %{{.*}}, {{.+}}* dereferenceable({{.+}}) %{{.+}}, {{.+}}* dereferenceable({{.+}}) %{{.+}}, {{.+}}* dereferenceable({{.+}}) %{{.+}})
439      // Capture d, Gd, Sd
440      #pragma omp parallel if(Gc>0.0 && c>0 && Sc>0.0)
441      {
442        d += 1;
443        Gd += 1.0;
444        Sd += 1.0;
445      }
446    }
447  }
448  return a + b + c + d + (int)Sa + (int)Sb + (int)Sc + (int)Sd;
449}
450
451int tbar2(short a, short b, short c, short d){
452  return tbar(a, b, c, d);
453}
454
455#endif
456