Clang Project

clang_source_code/test/OpenMP/for_linear_codegen.cpp
1// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
2// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s
3// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
4// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s
5// RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s
6
7// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
8// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s
9// RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-apple-darwin10 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s
10// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
11// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
12// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
13// expected-no-diagnostics
14#ifndef HEADER
15#define HEADER
16
17template <class T>
18struct S {
19  T f;
20  S(T a) : f(a) {}
21  S() : f() {}
22  S<T> &operator=(const S<T> &);
23  operator T() { return T(); }
24  ~S() {}
25};
26
27volatile int g = 1212;
28volatile int &g1 = g;
29float f;
30char cnt;
31
32struct SS {
33  int a;
34  int b : 4;
35  int &c;
36  SS(int &d) : a(0), b(0), c(d) {
37#pragma omp parallel
38#pragma omp for linear(a, b, c)
39    for (int i = 0; i < 2; ++i)
40#ifdef LAMBDA
41      [&]() {
42        ++this->a, --b, (this)->c /= 1;
43#pragma omp parallel
44#pragma omp for linear(a, b) linear(ref(c))
45        for (int i = 0; i < 2; ++i)
46          ++(this)->a, --b, this->c /= 1;
47      }();
48#elif defined(BLOCKS)
49      ^{
50        ++a;
51        --this->b;
52        (this)->c /= 1;
53#pragma omp parallel
54#pragma omp for linear(a, b) linear(uval(c))
55        for (int i = 0; i < 2; ++i)
56          ++(this)->a, --b, this->c /= 1;
57      }();
58#else
59      ++this->a, --b, c /= 1;
60#endif
61  }
62};
63
64template <typename T>
65struct SST {
66  T a;
67  SST() : a(T()) {
68#pragma omp parallel
69#pragma omp for linear(a)
70    for (int i = 0; i < 2; ++i)
71#ifdef LAMBDA
72      [&]() {
73        [&]() {
74          ++this->a;
75#pragma omp parallel
76#pragma omp for linear(a)
77          for (int i = 0; i < 2; ++i)
78            ++(this)->a;
79        }();
80      }();
81#elif defined(BLOCKS)
82      ^{
83        ^{
84          ++a;
85#pragma omp parallel
86#pragma omp for linear(a)
87          for (int i = 0; i < 2; ++i)
88            ++(this)->a;
89        }();
90      }();
91#else
92      ++(this)->a;
93#endif
94  }
95};
96
97// CHECK: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8
98// LAMBDA: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8
99// BLOCKS: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8
100// CHECK: [[S_FLOAT_TY:%.+]] = type { float }
101// CHECK: [[S_INT_TY:%.+]] = type { i32 }
102// CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr global %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8*
103// CHECK-DAG: [[F:@.+]] = global float 0.0
104// CHECK-DAG: [[CNT:@.+]] = global i8 0
105template <typename T>
106T tmain() {
107  S<T> test;
108  SST<T> sst;
109  T *pvar = &test.f;
110  T &lvar = test.f;
111#pragma omp parallel
112#pragma omp for linear(pvar, lvar)
113  for (int i = 0; i < 2; ++i) {
114    ++pvar, ++lvar;
115  }
116  return T();
117}
118
119int main() {
120  static int sivar;
121  SS ss(sivar);
122#ifdef LAMBDA
123  // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
124  // LAMBDA-LABEL: @main
125  // LAMBDA: alloca [[SS_TY]],
126  // LAMBDA: alloca [[CAP_TY:%.+]],
127  // LAMBDA: call void [[OUTER_LAMBDA:@.+]]([[CAP_TY]]*
128  [&]() {
129  // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
130  // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, {{.+}}* [[OMP_REGION:@.+]] to {{.+}})
131#pragma omp parallel
132#pragma omp for linear(g, g1:5)
133  for (int i = 0; i < 2; ++i) {
134    // LAMBDA: define {{.+}} @{{.+}}([[SS_TY]]*
135    // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
136    // LAMBDA: store i{{[0-9]+}} 0, i{{[0-9]+}}* %
137    // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
138    // LAMBDA: store i8
139    // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
140    // LAMBDA: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void
141    // LAMBDA: ret
142
143    // LAMBDA: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}})
144    // LAMBDA: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 0
145    // LAMBDA-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1
146    // LAMBDA: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 2
147    // LAMBDA: call void @__kmpc_for_static_init_4(
148    // LAMBDA-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]*
149    // LAMBDA: call{{.*}} void
150    // LAMBDA: call void @__kmpc_for_static_fini(
151    // LAMBDA: br i1
152    // LAMBDA: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1
153    // LAMBDA: store i8 %{{.+}}, i8* [[B_REF]],
154    // LAMBDA: br label
155    // LAMBDA: ret void
156
157    // LAMBDA: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, i32* {{.+}}, i32* {{.+}}, i32* {{.+}})
158    // LAMBDA: alloca i{{[0-9]+}},
159    // LAMBDA: alloca i{{[0-9]+}},
160    // LAMBDA: alloca i{{[0-9]+}},
161    // LAMBDA: alloca i{{[0-9]+}},
162    // LAMBDA: alloca i{{[0-9]+}},
163    // LAMBDA: alloca i{{[0-9]+}},
164    // LAMBDA: alloca i{{[0-9]+}},
165    // LAMBDA: alloca i{{[0-9]+}},
166    // LAMBDA: alloca i{{[0-9]+}},
167    // LAMBDA: alloca i{{[0-9]+}},
168    // LAMBDA: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
169    // LAMBDA: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
170    // LAMBDA: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
171    // LAMBDA: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]],
172    // LAMBDA: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]],
173    // LAMBDA: call void @__kmpc_for_static_init_4(
174    // LAMBDA: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]],
175    // LAMBDA-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]],
176    // LAMBDA-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1
177    // LAMBDA-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]],
178    // LAMBDA-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]],
179    // LAMBDA-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1
180    // LAMBDA-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]],
181    // LAMBDA-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]],
182    // LAMBDA-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]],
183    // LAMBDA-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1
184    // LAMBDA-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]],
185    // LAMBDA: call void @__kmpc_for_static_fini(
186    // LAMBDA: br i1
187    // LAMBDA: br label
188    // LAMBDA: ret void
189
190    // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}})
191    // LAMBDA: alloca i{{[0-9]+}},
192    // LAMBDA: alloca i{{[0-9]+}},
193    // LAMBDA: [[G_START_ADDR:%.+]] = alloca i{{[0-9]+}},
194    // LAMBDA: alloca i{{[0-9]+}},
195    // LAMBDA: alloca i{{[0-9]+}},
196    // LAMBDA: alloca i{{[0-9]+}},
197    // LAMBDA: alloca i{{[0-9]+}},
198    // LAMBDA: alloca i{{[0-9]+}},
199    // LAMBDA: alloca i{{[0-9]+}},
200    // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
201    // LAMBDA: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}}
202    // LAMBDA: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
203    // LAMBDA: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1)
204    // LAMBDA: [[VAL:%.+]] = load i32, i32* [[G_START_ADDR]]
205    // LAMBDA: [[CNT:%.+]] = load i32, i32*
206    // LAMBDA: [[MUL:%.+]] = mul nsw i32 [[CNT]], 5
207    // LAMBDA: [[ADD:%.+]] = add nsw i32 [[VAL]], [[MUL]]
208    // LAMBDA: store i32 [[ADD]], i32* [[G_PRIVATE_ADDR]],
209    // LAMBDA: [[VAL:%.+]] = load i32, i32* [[G_PRIVATE_ADDR]],
210    // LAMBDA: [[ADD:%.+]] = add nsw i32 [[VAL]], 5
211    // LAMBDA: store i32 [[ADD]], i32* [[G_PRIVATE_ADDR]],
212    // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
213    // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]]
214    // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
215    // LAMBDA: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]])
216    g += 5;
217    g1 += 5;
218    // LAMBDA: call void @__kmpc_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]])
219    [&]() {
220      // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
221      // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
222      g = 2;
223      g1 = 2;
224      // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
225      // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
226      // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]]
227      // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]]
228    }();
229  }
230  }();
231  return 0;
232#elif defined(BLOCKS)
233  // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212,
234  // BLOCKS-LABEL: @main
235  // BLOCKS: call
236  // BLOCKS: call void {{%.+}}(i8
237  ^{
238  // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
239  // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, {{.+}}* [[OMP_REGION:@.+]] to {{.+}})
240#pragma omp parallel
241#pragma omp for linear(g, g1:5)
242  for (int i = 0; i < 2; ++i) {
243    // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}})
244    // BLOCKS: alloca i{{[0-9]+}},
245    // BLOCKS: alloca i{{[0-9]+}},
246    // BLOCKS: [[G_START_ADDR:%.+]] = alloca i{{[0-9]+}},
247    // BLOCKS: alloca i{{[0-9]+}},
248    // BLOCKS: alloca i{{[0-9]+}},
249    // BLOCKS: alloca i{{[0-9]+}},
250    // BLOCKS: alloca i{{[0-9]+}},
251    // BLOCKS: alloca i{{[0-9]+}},
252    // BLOCKS: alloca i{{[0-9]+}},
253    // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
254    // BLOCKS: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}}
255    // BLOCKS: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
256    // BLOCKS: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1)
257    // BLOCKS: [[VAL:%.+]] = load i32, i32* [[G_START_ADDR]]
258    // BLOCKS: [[CNT:%.+]] = load i32, i32*
259    // BLOCKS: [[MUL:%.+]] = mul nsw i32 [[CNT]], 5
260    // BLOCKS: [[ADD:%.+]] = add nsw i32 [[VAL]], [[MUL]]
261    // BLOCKS: store i32 [[ADD]], i32* [[G_PRIVATE_ADDR]],
262    // BLOCKS: [[VAL:%.+]] = load i32, i32* [[G_PRIVATE_ADDR]],
263    // BLOCKS: [[ADD:%.+]] = add nsw i32 [[VAL]], 5
264    // BLOCKS: store i32 [[ADD]], i32* [[G_PRIVATE_ADDR]],
265    // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
266    // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]]
267    // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
268    // BLOCKS: call void {{%.+}}(i8
269    // BLOCKS: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]])
270    g += 5;
271    g1 += 5;
272    // BLOCKS: call void @__kmpc_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]])
273    g = 1;
274    g1 = 5;
275    ^{
276      // BLOCKS: define {{.+}} void {{@.+}}(i8*
277      g = 2;
278      g1 = 2;
279      // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
280      // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}*
281      // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
282      // BLOCKS: ret
283    }();
284  }
285  }();
286  return 0;
287// BLOCKS: define {{.+}} @{{.+}}([[SS_TY]]*
288// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
289// BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* %
290// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
291// BLOCKS: store i8
292// BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
293// BLOCKS: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void
294// BLOCKS: ret
295
296// BLOCKS: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}})
297// BLOCKS: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 0
298// BLOCKS-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1
299// BLOCKS: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 2
300// BLOCKS: call void @__kmpc_for_static_init_4(
301// BLOCKS-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]*
302// BLOCKS: call{{.*}} void
303// BLOCKS: call void @__kmpc_for_static_fini(
304// BLOCKS: br i1
305// BLOCKS: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1
306// BLOCKS: store i8 %{{.+}}, i8* [[B_REF]],
307// BLOCKS: br label
308// BLOCKS: ret void
309
310// BLOCKS: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, i32* {{.+}}, i32* {{.+}}, i32* {{.+}})
311// BLOCKS: alloca i{{[0-9]+}},
312// BLOCKS: alloca i{{[0-9]+}},
313// BLOCKS: alloca i{{[0-9]+}},
314// BLOCKS: alloca i{{[0-9]+}},
315// BLOCKS: alloca i{{[0-9]+}},
316// BLOCKS: alloca i{{[0-9]+}},
317// BLOCKS: alloca i{{[0-9]+}},
318// BLOCKS: alloca i{{[0-9]+}},
319// BLOCKS: alloca i{{[0-9]+}},
320// BLOCKS: alloca i{{[0-9]+}},
321// BLOCKS: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
322// BLOCKS: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
323// BLOCKS: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
324// BLOCKS: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]],
325// BLOCKS: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]],
326// BLOCKS: call void @__kmpc_for_static_init_4(
327// BLOCKS: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]],
328// BLOCKS-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]],
329// BLOCKS-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1
330// BLOCKS-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]],
331// BLOCKS-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]],
332// BLOCKS-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1
333// BLOCKS-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]],
334// BLOCKS-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]],
335// BLOCKS-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]],
336// BLOCKS-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1
337// BLOCKS-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]],
338// BLOCKS: call void @__kmpc_for_static_fini(
339// BLOCKS: br i1
340// BLOCKS: br label
341// BLOCKS: ret void
342#else
343  S<float> test;
344  float *pvar = &test.f;
345  long long lvar = 0;
346#pragma omp parallel
347#pragma omp for linear(pvar, lvar : 3)
348  for (int i = 0; i < 2; ++i) {
349    pvar += 3, lvar += 3;
350  }
351  return tmain<int>();
352#endif
353}
354
355// CHECK: define i{{[0-9]+}} @main()
356// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
357// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
358// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 2, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, float**, i64*)* [[MAIN_MICROTASK:@.+]] to void
359// CHECK: = call {{.+}} [[TMAIN_INT:@.+]]()
360// CHECK: call void [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]*
361// CHECK: ret
362
363// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, float** dereferenceable(8) %{{.+}}, i64* dereferenceable(8) %{{.+}})
364// CHECK: alloca i{{[0-9]+}},
365// CHECK: alloca i{{[0-9]+}},
366// CHECK: [[PVAR_START:%.+]] = alloca float*,
367// CHECK: [[LVAR_START:%.+]] = alloca i64,
368// CHECK: alloca i{{[0-9]+}},
369// CHECK: alloca i{{[0-9]+}},
370// CHECK: alloca i{{[0-9]+}},
371// CHECK: alloca i{{[0-9]+}},
372// CHECK: [[PVAR_PRIV:%.+]] = alloca float*,
373// CHECK: [[LVAR_PRIV:%.+]] = alloca i64,
374// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]]
375
376// Check for default initialization.
377// CHECK: [[PVAR_REF:%.+]] = load float**, float*** %
378// CHECK: [[LVAR_REF:%.+]] = load i64*, i64** %
379// CHECK: [[PVAR_VAL:%.+]] = load float*, float** [[PVAR_REF]],
380// CHECK: store float* [[PVAR_VAL]], float** [[PVAR_START]],
381// CHECK: [[LVAR_VAL:%.+]] = load i64, i64* [[LVAR_REF]],
382// CHECK: store i64 [[LVAR_VAL]], i64* [[LVAR_START]],
383// CHECK: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID:%.+]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1)
384// CHECK: [[PVAR_VAL:%.+]] = load float*, float** [[PVAR_START]],
385// CHECK: [[CNT:%.+]] = load i32, i32*
386// CHECK: [[MUL:%.+]] = mul nsw i32 [[CNT]], 3
387// CHECK: [[IDX:%.+]] = sext i32 [[MUL]] to i64
388// CHECK: [[PTR:%.+]] = getelementptr inbounds float, float* [[PVAR_VAL]], i64 [[IDX]]
389// CHECK: store float* [[PTR]], float** [[PVAR_PRIV]],
390// CHECK: [[LVAR_VAL:%.+]] = load i64, i64* [[LVAR_START]],
391// CHECK: [[CNT:%.+]] = load i32, i32*
392// CHECK: [[MUL:%.+]] = mul nsw i32 [[CNT]], 3
393// CHECK: [[CONV:%.+]] = sext i32 [[MUL]] to i64
394// CHECK: [[VAL:%.+]] = add nsw i64 [[LVAR_VAL]], [[CONV]]
395// CHECK: store i64 [[VAL]], i64* [[LVAR_PRIV]],
396// CHECK: [[PVAR_VAL:%.+]] = load float*, float** [[PVAR_PRIV]]
397// CHECK: [[PTR:%.+]] = getelementptr inbounds float, float* [[PVAR_VAL]], i64 3
398// CHECK: store float* [[PTR]], float** [[PVAR_PRIV]],
399// CHECK: [[LVAR_VAL:%.+]] = load i64, i64* [[LVAR_PRIV]],
400// CHECK: [[ADD:%.+]] = add nsw i64 [[LVAR_VAL]], 3
401// CHECK: store i64 [[ADD]], i64* [[LVAR_PRIV]],
402// CHECK: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 %{{.+}})
403// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
404// CHECK: ret void
405
406// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
407// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
408// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
409// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 2, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i32**, i32*)* [[TMAIN_MICROTASK:@.+]] to void
410// CHECK: call void [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
411// CHECK: ret
412
413// CHECK: define {{.+}} @{{.+}}([[SS_TY]]*
414// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
415// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* %
416// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1
417// CHECK: store i8
418// CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2
419// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void
420// CHECK: ret
421
422// CHECK: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}})
423// CHECK: alloca i{{[0-9]+}},
424// CHECK: alloca i{{[0-9]+}},
425// CHECK: alloca i{{[0-9]+}},
426// CHECK: alloca i{{[0-9]+}},
427// CHECK: alloca i{{[0-9]+}},
428// CHECK: alloca i{{[0-9]+}},
429// CHECK: alloca i{{[0-9]+}},
430// CHECK: alloca i{{[0-9]+}},
431// CHECK: alloca i{{[0-9]+}},
432// CHECK: alloca i{{[0-9]+}},
433// CHECK: alloca i{{[0-9]+}},
434// CHECK: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
435// CHECK: [[B_PRIV:%.+]] = alloca i{{[0-9]+}},
436// CHECK: [[C_PRIV:%.+]] = alloca i{{[0-9]+}},
437// CHECK: call void @__kmpc_barrier(
438// CHECK: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]],
439// CHECK: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]],
440// CHECK: call void @__kmpc_for_static_init_4(
441// CHECK: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]],
442// CHECK-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]],
443// CHECK-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1
444// CHECK-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]],
445// CHECK-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]],
446// CHECK-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1
447// CHECK-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]],
448// CHECK-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]],
449// CHECK-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]],
450// CHECK-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1
451// CHECK-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]],
452// CHECK: call void @__kmpc_for_static_fini(
453// CHECK: br i1
454// CHECK: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1
455// CHECK: store i8 %{{.+}}, i8* [[B_REF]],
456// CHECK: br label
457// CHECK: ret void
458
459// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i32** dereferenceable(8) %{{.+}}, i32* dereferenceable(4) %{{.+}})
460// CHECK: alloca i{{[0-9]+}},
461// CHECK: alloca i{{[0-9]+}},
462// CHECK: [[PVAR_START:%.+]] = alloca i32*,
463// CHECK: [[LVAR_START:%.+]] = alloca i32,
464// CHECK: alloca i{{[0-9]+}},
465// CHECK: alloca i{{[0-9]+}},
466// CHECK: alloca i{{[0-9]+}},
467// CHECK: alloca i{{[0-9]+}},
468// CHECK: [[PVAR_PRIV:%.+]] = alloca i32*,
469// CHECK: [[LVAR_PRIV:%.+]] = alloca i32,
470// CHECK: [[LVAR_PRIV_REF:%.+]] = alloca i32*,
471// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]]
472
473// Check for default initialization.
474// CHECK: [[PVAR_REF:%.+]] = load i32**, i32*** %
475// CHECK: [[PVAR_VAL:%.+]] = load i32*, i32** [[PVAR_REF]],
476// CHECK: store i32* [[PVAR_VAL]], i32** [[PVAR_START]],
477// CHECK: [[LVAR_REF:%.+]] = load i32*, i32** %
478// CHECK: [[LVAR_VAL:%.+]] = load i32, i32* [[LVAR_REF]],
479// CHECK: store i32 [[LVAR_VAL]], i32* [[LVAR_START]],
480// CHECK: store i32* [[LVAR_PRIV]], i32** [[LVAR_PRIV_REF]],
481
482// CHECK: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID:%.+]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1)
483// CHECK: [[PVAR_VAL:%.+]] = load i32*, i32** [[PVAR_START]],
484// CHECK: [[CNT:%.+]] = load i32, i32*
485// CHECK: [[MUL:%.+]] = mul nsw i32 [[CNT]], 1
486// CHECK: [[IDX:%.+]] = sext i32 [[MUL]] to i64
487// CHECK: [[PTR:%.+]] = getelementptr inbounds i32, i32* [[PVAR_VAL]], i64 [[IDX]]
488// CHECK: store i32* [[PTR]], i32** [[PVAR_PRIV]],
489// CHECK: [[LVAR_VAL:%.+]] = load i32, i32* [[LVAR_START]],
490// CHECK: [[CNT:%.+]] = load i32, i32*
491// CHECK: [[MUL:%.+]] = mul nsw i32 [[CNT]], 1
492// CHECK: [[VAL:%.+]] = add nsw i32 [[LVAR_VAL]], [[MUL]]
493// CHECK: store i32 [[VAL]], i32* [[LVAR_PRIV]],
494// CHECK: [[PVAR_VAL:%.+]] = load i32*, i32** [[PVAR_PRIV]]
495// CHECK: [[PTR:%.+]] = getelementptr inbounds i32, i32* [[PVAR_VAL]], i32 1
496// CHECK: store i32* [[PTR]], i32** [[PVAR_PRIV]],
497// CHECK: [[LVAR_PRIV:%.+]] = load i32*, i32** [[LVAR_PRIV_REF]],
498// CHECK: [[LVAR_VAL:%.+]] = load i32, i32* [[LVAR_PRIV]],
499// CHECK: [[ADD:%.+]] = add nsw i32 [[LVAR_VAL]], 1
500// CHECK: store i32 [[ADD]], i32* [[LVAR_PRIV]],
501// CHECK: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 %{{.+}})
502// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
503// CHECK: ret void
504#endif
505
506