blob: 6763686dd0fc811a86f09c827f29f7a0d21c2f2b [file] [log] [blame]
Alexey Bataevdb390212015-05-20 04:24:19 +00001// 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
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +00006// expected-no-diagnostics
7#ifndef HEADER
8#define HEADER
9
10volatile double g;
11
12template <class T>
13struct S {
14 T f;
15 S(T a) : f(a + g) {}
16 S() : f(g) {}
17 operator T() { return T(); }
18 S &operator&(const S &) { return *this; }
19 ~S() {}
20};
21
22// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float }
23// CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
24// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { float*, [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]*, float*, [2 x i{{[0-9]+}}]*, [2 x [[S_FLOAT_TY]]]* }
25// CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { i{{[0-9]+}}*, [[S_INT_TY]]*, [[S_INT_TY]]*, i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_INT_TY]]]* }
26// CHECK-DAG: [[ATOMIC_REDUCE_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 18, i32 0, i32 0, i8*
27// CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8*
28// CHECK-DAG: [[REDUCTION_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 18, i32 0, i32 0, i8*
29// CHECK-DAG: [[REDUCTION_LOCK:@.+]] = common global [8 x i32] zeroinitializer
30
31template <typename T>
32T tmain() {
33 T t;
34 S<T> test;
35 T t_var = T(), t_var1;
36 T vec[] = {1, 2};
37 S<T> s_arr[] = {1, 2};
38 S<T> var(3), var1;
39#pragma omp parallel
40#pragma omp for reduction(+:t_var) reduction(&:var) reduction(&& : var1) reduction(min: t_var1) nowait
41 for (int i = 0; i < 2; ++i) {
42 vec[i] = t_var;
43 s_arr[i] = var;
44 }
Alexey Bataev19fa2c32015-04-29 05:21:03 +000045#pragma omp parallel
46#pragma omp for reduction(&& : t_var)
47 for (int i = 0; i < 2; ++i) {
48 vec[i] = t_var;
49 s_arr[i] = var;
50 }
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +000051 return T();
52}
53
54int main() {
55#ifdef LAMBDA
56 // LAMBDA: [[G:@.+]] = global double
57 // LAMBDA-LABEL: @main
58 // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
59 [&]() {
60 // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
61 // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}})
62#pragma omp parallel
63#pragma omp for reduction(+:g)
64 for (int i = 0; i < 2; ++i) {
65 // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* %{{.+}})
66 // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double,
67
68 // Reduction list for runtime.
69 // LAMBDA: [[RED_LIST:%.+]] = alloca [1 x i8*],
70
71 // LAMBDA: store double 0.0{{.+}}, double* [[G_PRIVATE_ADDR]]
72 // LAMBDA: call void @__kmpc_for_static_init_4(
73 g = 1;
74 // LAMBDA: store volatile double 1.0{{.+}}, double* [[G_PRIVATE_ADDR]],
75 // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
76 // LAMBDA: store double* [[G_PRIVATE_ADDR]], double** [[G_PRIVATE_ADDR_REF]]
77 // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
78 // LAMBDA: call void @__kmpc_for_static_fini(
79
80 // LAMBDA: [[G_PRIV_REF:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RED_LIST]], i32 0, i32 0
81 // LAMBDA: [[BITCAST:%.+]] = bitcast double* [[G_PRIVATE_ADDR]] to i8*
82 // LAMBDA: store i8* [[BITCAST]], i8** [[G_PRIV_REF]],
83 // LAMBDA: call i32 @__kmpc_reduce(
84 // LAMBDA: switch i32 %{{.+}}, label %[[REDUCTION_DONE:.+]] [
85 // LAMBDA: i32 1, label %[[CASE1:.+]]
86 // LAMBDA: i32 2, label %[[CASE2:.+]]
87 // LAMBDA: [[CASE1]]
88 // LAMBDA: [[G_VAL:%.+]] = load double, double* [[G]]
89 // LAMBDA: [[G_PRIV_VAL:%.+]] = load double, double* [[G_PRIVATE_ADDR]]
90 // LAMBDA: [[ADD:%.+]] = fadd double [[G_VAL]], [[G_PRIV_VAL]]
91 // LAMBDA: store double [[ADD]], double* [[G]]
92 // LAMBDA: call void @__kmpc_end_reduce(
93 // LAMBDA: br label %[[REDUCTION_DONE]]
94 // LAMBDA: [[CASE2]]
95 // LAMBDA: [[G_PRIV_VAL:%.+]] = load double, double* [[G_PRIVATE_ADDR]]
96 // LAMBDA: fadd double
97 // LAMBDA: cmpxchg i64*
Alexey Bataev69a47792015-05-07 03:54:03 +000098 // LAMBDA: call void @__kmpc_end_reduce(
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +000099 // LAMBDA: br label %[[REDUCTION_DONE]]
100 // LAMBDA: [[REDUCTION_DONE]]
101 // LAMBDA: ret void
102 [&]() {
103 // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
104 // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
105 g = 2;
106 // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
107 // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
108 // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]]
109 // LAMBDA: store volatile double 2.0{{.+}}, double* [[G_REF]]
110 }();
111 }
112 }();
113 return 0;
114#elif defined(BLOCKS)
115 // BLOCKS: [[G:@.+]] = global double
116 // BLOCKS-LABEL: @main
117 // BLOCKS: call void {{%.+}}(i8
118 ^{
119 // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
120 // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}})
121#pragma omp parallel
122#pragma omp for reduction(-:g)
123 for (int i = 0; i < 2; ++i) {
124 // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* %{{.+}})
125 // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca double,
126
127 // Reduction list for runtime.
128 // BLOCKS: [[RED_LIST:%.+]] = alloca [1 x i8*],
129
130 // BLOCKS: store double 0.0{{.+}}, double* [[G_PRIVATE_ADDR]]
131 g = 1;
132 // BLOCKS: call void @__kmpc_for_static_init_4(
133 // BLOCKS: store volatile double 1.0{{.+}}, double* [[G_PRIVATE_ADDR]],
134 // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
135 // BLOCKS: double* [[G_PRIVATE_ADDR]]
136 // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
137 // BLOCKS: call void {{%.+}}(i8
138 // BLOCKS: call void @__kmpc_for_static_fini(
139
140 // BLOCKS: [[G_PRIV_REF:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RED_LIST]], i32 0, i32 0
141 // BLOCKS: [[BITCAST:%.+]] = bitcast double* [[G_PRIVATE_ADDR]] to i8*
142 // BLOCKS: store i8* [[BITCAST]], i8** [[G_PRIV_REF]],
143 // BLOCKS: call i32 @__kmpc_reduce(
144 // BLOCKS: switch i32 %{{.+}}, label %[[REDUCTION_DONE:.+]] [
145 // BLOCKS: i32 1, label %[[CASE1:.+]]
146 // BLOCKS: i32 2, label %[[CASE2:.+]]
147 // BLOCKS: [[CASE1]]
148 // BLOCKS: [[G_VAL:%.+]] = load double, double* [[G]]
149 // BLOCKS: [[G_PRIV_VAL:%.+]] = load double, double* [[G_PRIVATE_ADDR]]
150 // BLOCKS: [[ADD:%.+]] = fadd double [[G_VAL]], [[G_PRIV_VAL]]
151 // BLOCKS: store double [[ADD]], double* [[G]]
152 // BLOCKS: call void @__kmpc_end_reduce(
153 // BLOCKS: br label %[[REDUCTION_DONE]]
154 // BLOCKS: [[CASE2]]
155 // BLOCKS: [[G_PRIV_VAL:%.+]] = load double, double* [[G_PRIVATE_ADDR]]
156 // BLOCKS: fadd double
157 // BLOCKS: cmpxchg i64*
Alexey Bataev69a47792015-05-07 03:54:03 +0000158 // BLOCKS: call void @__kmpc_end_reduce(
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000159 // BLOCKS: br label %[[REDUCTION_DONE]]
160 // BLOCKS: [[REDUCTION_DONE]]
161 // BLOCKS: ret void
162 ^{
163 // BLOCKS: define {{.+}} void {{@.+}}(i8*
164 g = 2;
165 // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
166 // BLOCKS: store volatile double 2.0{{.+}}, double*
167 // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
168 // BLOCKS: ret
169 }();
170 }
171 }();
172 return 0;
173#else
174 S<float> test;
175 float t_var = 0, t_var1;
176 int vec[] = {1, 2};
177 S<float> s_arr[] = {1, 2};
178 S<float> var(3), var1;
179#pragma omp parallel
180#pragma omp for reduction(+:t_var) reduction(&:var) reduction(&& : var1) reduction(min: t_var1)
181 for (int i = 0; i < 2; ++i) {
182 vec[i] = t_var;
183 s_arr[i] = var;
184 }
185 return tmain<int>();
186#endif
187}
188
189// CHECK: define {{.*}}i{{[0-9]+}} @main()
190// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
191// CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
192// CHECK: %{{.+}} = bitcast [[CAP_MAIN_TY]]*
193// 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]+}}*, [[CAP_MAIN_TY]]*)* [[MAIN_MICROTASK:@.+]] to void
194// CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]()
195// CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]*
196// CHECK: ret
197//
198// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_MAIN_TY]]* %{{.+}})
199// CHECK: [[T_VAR_PRIV:%.+]] = alloca float,
200// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
201// CHECK: [[VAR1_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
202// CHECK: [[T_VAR1_PRIV:%.+]] = alloca float,
203
204// Reduction list for runtime.
205// CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*],
206
207// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
208
209// CHECK: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}}
210// CHECK: [[T_VAR_REF:%.+]] = load float*, float** [[T_VAR_PTR_REF]],
211// For + reduction operation initial value of private variable is 0.
212// CHECK: store float 0.0{{.+}}, float* [[T_VAR_PRIV]],
213
214// CHECK: [[VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}}
215// CHECK: [[VAR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_PTR_REF:%.+]],
216// For & reduction operation initial value of private variable is ones in all bits.
217// CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
218
219// CHECK: [[VAR1_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}}
220// CHECK: [[VAR1_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_PTR_REF:%.+]],
221// For && reduction operation initial value of private variable is 1.0.
222// CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[VAR1_PRIV]])
223
224// CHECK: [[T_VAR1_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}}
225// CHECK: [[T_VAR1_REF:%.+]] = load float*, float** [[T_VAR1_PTR_REF]],
226// For min reduction operation initial value of private variable is largest repesentable value.
227// CHECK: store float 0x47EFFFFFE0000000, float* [[T_VAR1_PRIV]],
228
229
230// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
231// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
232// CHECK: call void @__kmpc_for_static_init_4(
233// Skip checks for internal operations.
234// CHECK: call void @__kmpc_for_static_fini(
235
236// void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
237
238// CHECK: [[T_VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 0
239// CHECK: [[BITCAST:%.+]] = bitcast float* [[T_VAR_PRIV]] to i8*
240// CHECK: store i8* [[BITCAST]], i8** [[T_VAR_PRIV_REF]],
241// CHECK: [[VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 1
242// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_PRIV]] to i8*
243// CHECK: store i8* [[BITCAST]], i8** [[VAR_PRIV_REF]],
244// CHECK: [[VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 2
245// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR1_PRIV]] to i8*
246// CHECK: store i8* [[BITCAST]], i8** [[VAR1_PRIV_REF]],
247// CHECK: [[T_VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 3
248// CHECK: [[BITCAST:%.+]] = bitcast float* [[T_VAR1_PRIV]] to i8*
249// CHECK: store i8* [[BITCAST]], i8** [[T_VAR1_PRIV_REF]],
250
251// res = __kmpc_reduce(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>);
252
253// CHECK: [[BITCAST:%.+]] = bitcast [4 x i8*]* [[RED_LIST]] to i8*
254// CHECK: [[RES:%.+]] = call i32 @__kmpc_reduce(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], i32 4, i64 32, i8* [[BITCAST]], void (i8*, i8*)* [[REDUCTION_FUNC:@.+]], [8 x i32]* [[REDUCTION_LOCK]])
255
256// switch(res)
257// CHECK: switch i32 [[RES]], label %[[RED_DONE:.+]] [
258// CHECK: i32 1, label %[[CASE1:.+]]
259// CHECK: i32 2, label %[[CASE2:.+]]
260// CHECK: ]
261
262// case 1:
263// t_var += t_var_reduction;
264// CHECK: [[T_VAR_VAL:%.+]] = load float, float* [[T_VAR_REF]],
265// CHECK: [[T_VAR_PRIV_VAL:%.+]] = load float, float* [[T_VAR_PRIV]],
266// CHECK: [[UP:%.+]] = fadd float [[T_VAR_VAL]], [[T_VAR_PRIV_VAL]]
267// CHECK: store float [[UP]], float* [[T_VAR_REF]],
268
269// var = var.operator &(var_reduction);
270// CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_FLOAT_TY]]* @{{.+}}([[S_FLOAT_TY]]* [[VAR_REF]], [[S_FLOAT_TY]]* dereferenceable(4) [[VAR_PRIV]])
271// CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_REF]] to i8*
272// CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[UP]] to i8*
273// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
274
275// var1 = var1.operator &&(var1_reduction);
276// CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_REF]])
277// CHECK: [[VAR1_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0
Alexey Bataev69a47792015-05-07 03:54:03 +0000278// CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[END2:.+]]
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000279// CHECK: [[TRUE]]
280// CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_PRIV]])
281// CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000282// CHECK: br label %[[END2]]
283// CHECK: [[END2]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000284// CHECK: [[COND_LVALUE:%.+]] = phi i1 [ false, %{{.+}} ], [ [[VAR1_REDUCTION_BOOL]], %[[TRUE]] ]
285// CHECK: [[CONV:%.+]] = uitofp i1 [[COND_LVALUE]] to float
286// CHECK: call void @{{.+}}([[S_FLOAT_TY]]* [[COND_LVALUE:%.+]], float [[CONV]])
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000287// CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR1_REF]] to i8*
288// CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[COND_LVALUE]] to i8*
289// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
290
291// t_var1 = min(t_var1, t_var1_reduction);
292// CHECK: [[T_VAR1_VAL:%.+]] = load float, float* [[T_VAR1_REF]],
293// CHECK: [[T_VAR1_PRIV_VAL:%.+]] = load float, float* [[T_VAR1_PRIV]],
294// CHECK: [[CMP:%.+]] = fcmp olt float [[T_VAR1_VAL]], [[T_VAR1_PRIV_VAL]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000295// CHECK: br i1 [[CMP]]
296// CHECK: [[UP:%.+]] = phi float
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000297// CHECK: store float [[UP]], float* [[T_VAR1_REF]],
298
299// __kmpc_end_reduce(<loc>, <gtid>, &<lock>);
300// CHECK: call void @__kmpc_end_reduce(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]])
301
302// break;
303// CHECK: br label %[[RED_DONE]]
304
305// case 2:
306// t_var += t_var_reduction;
307// CHECK: load float, float* [[T_VAR_PRIV]]
308// CHECK: [[T_VAR_REF_INT:%.+]] = bitcast float* [[T_VAR_REF]] to i32*
Alexey Bataevf0ab5532015-05-15 08:36:34 +0000309// CHECK: [[OLD1:%.+]] = load atomic i32, i32* [[T_VAR_REF_INT]] monotonic,
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000310// CHECK: br label %[[CONT:.+]]
311// CHECK: [[CONT]]
Alexey Bataevf0ab5532015-05-15 08:36:34 +0000312// CHECK: [[ORIG_OLD_INT:%.+]] = phi i32 [ [[OLD1]], %{{.+}} ], [ [[OLD2:%.+]], %[[CONT]] ]
313// CHECK: fadd float
314// CHECK: [[UP_INT:%.+]] = load i32, i32*
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000315// CHECK: [[T_VAR_REF_INT:%.+]] = bitcast float* [[T_VAR_REF]] to i32*
316// CHECK: [[RES:%.+]] = cmpxchg i32* [[T_VAR_REF_INT]], i32 [[ORIG_OLD_INT]], i32 [[UP_INT]] monotonic monotonic
Alexey Bataevf0ab5532015-05-15 08:36:34 +0000317// CHECK: [[OLD2:%.+]] = extractvalue { i32, i1 } [[RES]], 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000318// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i32, i1 } [[RES]], 1
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000319// CHECK: br i1 [[SUCCESS_FAIL]], label %[[ATOMIC_DONE:.+]], label %[[CONT]]
320// CHECK: [[ATOMIC_DONE]]
321
322// var = var.operator &(var_reduction);
323// CHECK: call void @__kmpc_critical(
324// CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_FLOAT_TY]]* @{{.+}}([[S_FLOAT_TY]]* [[VAR_REF]], [[S_FLOAT_TY]]* dereferenceable(4) [[VAR_PRIV]])
325// CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_REF]] to i8*
326// CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[UP]] to i8*
327// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
328// CHECK: call void @__kmpc_end_critical(
329
330// var1 = var1.operator &&(var1_reduction);
331// CHECK: call void @__kmpc_critical(
332// CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_REF]])
333// CHECK: [[VAR1_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0
Alexey Bataev69a47792015-05-07 03:54:03 +0000334// CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[END2:.+]]
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000335// CHECK: [[TRUE]]
336// CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_PRIV]])
337// CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000338// CHECK: br label %[[END2]]
339// CHECK: [[END2]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000340// CHECK: [[COND_LVALUE:%.+]] = phi i1 [ false, %{{.+}} ], [ [[VAR1_REDUCTION_BOOL]], %[[TRUE]] ]
341// CHECK: [[CONV:%.+]] = uitofp i1 [[COND_LVALUE]] to float
342// CHECK: call void @{{.+}}([[S_FLOAT_TY]]* [[COND_LVALUE:%.+]], float [[CONV]])
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000343// CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR1_REF]] to i8*
344// CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[COND_LVALUE]] to i8*
345// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
346// CHECK: call void @__kmpc_end_critical(
347
348// t_var1 = min(t_var1, t_var1_reduction);
349// CHECK: load float, float* [[T_VAR1_PRIV]]
350// CHECK: [[T_VAR1_REF_INT:%.+]] = bitcast float* [[T_VAR1_REF]] to i32*
Alexey Bataevf0ab5532015-05-15 08:36:34 +0000351// CHECK: [[OLD1:%.+]] = load atomic i32, i32* [[T_VAR1_REF_INT]] monotonic,
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000352// CHECK: br label %[[CONT:.+]]
353// CHECK: [[CONT]]
Alexey Bataevf0ab5532015-05-15 08:36:34 +0000354// CHECK: [[ORIG_OLD_INT:%.+]] = phi i32 [ [[OLD1]], %{{.+}} ], [ [[OLD2:%.+]], %{{.+}} ]
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000355// CHECK: [[CMP:%.+]] = fcmp olt float
Alexey Bataev69a47792015-05-07 03:54:03 +0000356// CHECK: br i1 [[CMP]]
Alexey Bataevf0ab5532015-05-15 08:36:34 +0000357// CHECK: phi float
358// CHECK: [[UP_INT:%.+]] = load i32
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000359// CHECK: [[T_VAR1_REF_INT:%.+]] = bitcast float* [[T_VAR1_REF]] to i32*
360// CHECK: [[RES:%.+]] = cmpxchg i32* [[T_VAR1_REF_INT]], i32 [[ORIG_OLD_INT]], i32 [[UP_INT]] monotonic monotonic
Alexey Bataevf0ab5532015-05-15 08:36:34 +0000361// CHECK: [[OLD2:%.+]] = extractvalue { i32, i1 } [[RES]], 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000362// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i32, i1 } [[RES]], 1
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000363// CHECK: br i1 [[SUCCESS_FAIL]], label %[[ATOMIC_DONE:.+]], label %[[CONT]]
364// CHECK: [[ATOMIC_DONE]]
365
Alexey Bataev69a47792015-05-07 03:54:03 +0000366// __kmpc_end_reduce(<loc>, <gtid>, &<lock>);
367// CHECK: call void @__kmpc_end_reduce(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]])
368
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000369// break;
370// CHECK: br label %[[RED_DONE]]
371// CHECK: [[RED_DONE]]
372// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
373// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]*
374// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
375// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
376
377// CHECK: ret void
378
379// void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
380// *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]);
381// ...
382// *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1],
383// *(Type<n>-1*)rhs[<n>-1]);
384// }
385// CHECK: define internal void [[REDUCTION_FUNC]](i8*, i8*)
386// t_var_lhs = (float*)lhs[0];
387// CHECK: [[T_VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS:%.+]], i32 0, i32 0
388// CHECK: [[T_VAR_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR_RHS_REF]],
389// CHECK: [[T_VAR_RHS:%.+]] = bitcast i8* [[T_VAR_RHS_VOID]] to float*
390// t_var_rhs = (float*)rhs[0];
391// CHECK: [[T_VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS:%.+]], i32 0, i32 0
392// CHECK: [[T_VAR_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR_LHS_REF]],
393// CHECK: [[T_VAR_LHS:%.+]] = bitcast i8* [[T_VAR_LHS_VOID]] to float*
394
395// var_lhs = (S<float>*)lhs[1];
396// CHECK: [[VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 1
397// CHECK: [[VAR_RHS_VOID:%.+]] = load i8*, i8** [[VAR_RHS_REF]],
398// CHECK: [[VAR_RHS:%.+]] = bitcast i8* [[VAR_RHS_VOID]] to [[S_FLOAT_TY]]*
399// var_rhs = (S<float>*)rhs[1];
400// CHECK: [[VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 1
401// CHECK: [[VAR_LHS_VOID:%.+]] = load i8*, i8** [[VAR_LHS_REF]],
402// CHECK: [[VAR_LHS:%.+]] = bitcast i8* [[VAR_LHS_VOID]] to [[S_FLOAT_TY]]*
403
404// var1_lhs = (S<float>*)lhs[2];
405// CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 2
406// CHECK: [[VAR1_RHS_VOID:%.+]] = load i8*, i8** [[VAR1_RHS_REF]],
407// CHECK: [[VAR1_RHS:%.+]] = bitcast i8* [[VAR1_RHS_VOID]] to [[S_FLOAT_TY]]*
408// var1_rhs = (S<float>*)rhs[2];
409// CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 2
410// CHECK: [[VAR1_LHS_VOID:%.+]] = load i8*, i8** [[VAR1_LHS_REF]],
411// CHECK: [[VAR1_LHS:%.+]] = bitcast i8* [[VAR1_LHS_VOID]] to [[S_FLOAT_TY]]*
412
413// t_var1_lhs = (float*)lhs[3];
414// CHECK: [[T_VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 3
415// CHECK: [[T_VAR1_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_RHS_REF]],
416// CHECK: [[T_VAR1_RHS:%.+]] = bitcast i8* [[T_VAR1_RHS_VOID]] to float*
417// t_var1_rhs = (float*)rhs[3];
418// CHECK: [[T_VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 3
419// CHECK: [[T_VAR1_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_LHS_REF]],
420// CHECK: [[T_VAR1_LHS:%.+]] = bitcast i8* [[T_VAR1_LHS_VOID]] to float*
421
422// t_var_lhs += t_var_rhs;
423// CHECK: [[T_VAR_LHS_VAL:%.+]] = load float, float* [[T_VAR_LHS]],
424// CHECK: [[T_VAR_RHS_VAL:%.+]] = load float, float* [[T_VAR_RHS]],
425// CHECK: [[UP:%.+]] = fadd float [[T_VAR_LHS_VAL]], [[T_VAR_RHS_VAL]]
426// CHECK: store float [[UP]], float* [[T_VAR_LHS]],
427
428// var_lhs = var_lhs.operator &(var_rhs);
429// CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_FLOAT_TY]]* @{{.+}}([[S_FLOAT_TY]]* [[VAR_LHS]], [[S_FLOAT_TY]]* dereferenceable(4) [[VAR_RHS]])
430// CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_LHS]] to i8*
431// CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[UP]] to i8*
432// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
433
434// var1_lhs = var1_lhs.operator &&(var1_rhs);
435// CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_LHS]])
436// CHECK: [[VAR1_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0
Alexey Bataev69a47792015-05-07 03:54:03 +0000437// CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[END2:.+]]
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000438// CHECK: [[TRUE]]
439// CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_RHS]])
440// CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000441// CHECK: br label %[[END2]]
442// CHECK: [[END2]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000443// CHECK: [[COND_LVALUE:%.+]] = phi i1 [ false, %{{.+}} ], [ [[VAR1_REDUCTION_BOOL]], %[[TRUE]] ]
444// CHECK: [[CONV:%.+]] = uitofp i1 [[COND_LVALUE]] to float
445// CHECK: call void @{{.+}}([[S_FLOAT_TY]]* [[COND_LVALUE:%.+]], float [[CONV]])
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000446// CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR1_LHS]] to i8*
447// CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[COND_LVALUE]] to i8*
448// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
449
450// t_var1_lhs = min(t_var1_lhs, t_var1_rhs);
451// CHECK: [[T_VAR1_LHS_VAL:%.+]] = load float, float* [[T_VAR1_LHS]],
452// CHECK: [[T_VAR1_RHS_VAL:%.+]] = load float, float* [[T_VAR1_RHS]],
453// CHECK: [[CMP:%.+]] = fcmp olt float [[T_VAR1_LHS_VAL]], [[T_VAR1_RHS_VAL]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000454// CHECK: br i1 [[CMP]]
455// CHECK: [[UP:%.+]] = phi float
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000456// CHECK: store float [[UP]], float* [[T_VAR1_LHS]],
457// CHECK: ret void
458
459// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
460// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
461// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
462// CHECK: %{{.+}} = bitcast [[CAP_TMAIN_TY]]*
463// 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]+}}*, [[CAP_TMAIN_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void
464// CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
465// CHECK: ret
466//
467// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_TMAIN_TY]]* %{{.+}})
468// CHECK: alloca i{{[0-9]+}},
469// CHECK: alloca i{{[0-9]+}},
470// CHECK: alloca i{{[0-9]+}},
471// CHECK: alloca i{{[0-9]+}},
472// CHECK: alloca i{{[0-9]+}},
473// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
474// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
475// CHECK: [[VAR1_PRIV:%.+]] = alloca [[S_INT_TY]],
476// CHECK: [[T_VAR1_PRIV:%.+]] = alloca i{{[0-9]+}},
477
478// Reduction list for runtime.
479// CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*],
480
481// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
482
483// CHECK: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}}
484// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_PTR_REF]],
485// For + reduction operation initial value of private variable is 0.
486// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[T_VAR_PRIV]],
487
488// CHECK: [[VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}}
489// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_PTR_REF:%.+]],
490// For & reduction operation initial value of private variable is ones in all bits.
491// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[VAR_PRIV]])
492
493// CHECK: [[VAR1_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}}
494// CHECK: [[VAR1_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_PTR_REF:%.+]],
495// For && reduction operation initial value of private variable is 1.0.
496// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[VAR1_PRIV]])
497
498// CHECK: [[T_VAR1_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}}
499// CHECK: [[T_VAR1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR1_PTR_REF]],
500// For min reduction operation initial value of private variable is largest repesentable value.
501// CHECK: store i{{[0-9]+}} 2147483647, i{{[0-9]+}}* [[T_VAR1_PRIV]],
502
503// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
504// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
505// CHECK: call void @__kmpc_for_static_init_4(
506// Skip checks for internal operations.
507// CHECK: call void @__kmpc_for_static_fini(
508
509// void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
510
511// CHECK: [[T_VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 0
512// CHECK: [[BITCAST:%.+]] = bitcast i{{[0-9]+}}* [[T_VAR_PRIV]] to i8*
513// CHECK: store i8* [[BITCAST]], i8** [[T_VAR_PRIV_REF]],
514// CHECK: [[VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 1
515// CHECK: [[BITCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR_PRIV]] to i8*
516// CHECK: store i8* [[BITCAST]], i8** [[VAR_PRIV_REF]],
517// CHECK: [[VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 2
518// CHECK: [[BITCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR1_PRIV]] to i8*
519// CHECK: store i8* [[BITCAST]], i8** [[VAR1_PRIV_REF]],
520// CHECK: [[T_VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 3
521// CHECK: [[BITCAST:%.+]] = bitcast i{{[0-9]+}}* [[T_VAR1_PRIV]] to i8*
522// CHECK: store i8* [[BITCAST]], i8** [[T_VAR1_PRIV_REF]],
523
524// res = __kmpc_reduce_nowait(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>);
525
526// CHECK: [[BITCAST:%.+]] = bitcast [4 x i8*]* [[RED_LIST]] to i8*
527// CHECK: [[RES:%.+]] = call i32 @__kmpc_reduce_nowait(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], i32 4, i64 32, i8* [[BITCAST]], void (i8*, i8*)* [[REDUCTION_FUNC:@.+]], [8 x i32]* [[REDUCTION_LOCK]])
528
529// switch(res)
530// CHECK: switch i32 [[RES]], label %[[RED_DONE:.+]] [
531// CHECK: i32 1, label %[[CASE1:.+]]
532// CHECK: i32 2, label %[[CASE2:.+]]
533// CHECK: ]
534
535// case 1:
536// t_var += t_var_reduction;
537// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]],
538// CHECK: [[T_VAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
539// CHECK: [[UP:%.+]] = add nsw i{{[0-9]+}} [[T_VAR_VAL]], [[T_VAR_PRIV_VAL]]
540// CHECK: store i{{[0-9]+}} [[UP]], i{{[0-9]+}}* [[T_VAR_REF]],
541
542// var = var.operator &(var_reduction);
543// CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_INT_TY]]* @{{.+}}([[S_INT_TY]]* [[VAR_REF]], [[S_INT_TY]]* dereferenceable(4) [[VAR_PRIV]])
544// CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR_REF]] to i8*
545// CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[UP]] to i8*
546// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
547
548// var1 = var1.operator &&(var1_reduction);
549// CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_REF]])
550// CHECK: [[VAR1_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0
Alexey Bataev69a47792015-05-07 03:54:03 +0000551// CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[END2:.+]]
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000552// CHECK: [[TRUE]]
553// CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_PRIV]])
554// CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000555// CHECK: br label %[[END2]]
556// CHECK: [[END2]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000557// CHECK: [[COND_LVALUE:%.+]] = phi i1 [ false, %{{.+}} ], [ [[VAR1_REDUCTION_BOOL]], %[[TRUE]] ]
558// CHECK: [[CONV:%.+]] = zext i1 [[COND_LVALUE]] to i32
559// CHECK: call void @{{.+}}([[S_INT_TY]]* [[COND_LVALUE:%.+]], i32 [[CONV]])
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000560// CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR1_REF]] to i8*
561// CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[COND_LVALUE]] to i8*
562// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
563
564// t_var1 = min(t_var1, t_var1_reduction);
565// CHECK: [[T_VAR1_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_REF]],
566// CHECK: [[T_VAR1_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_PRIV]],
567// CHECK: [[CMP:%.+]] = icmp slt i{{[0-9]+}} [[T_VAR1_VAL]], [[T_VAR1_PRIV_VAL]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000568// CHECK: br i1 [[CMP]]
569// CHECK: [[UP:%.+]] = phi i32
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000570// CHECK: store i{{[0-9]+}} [[UP]], i{{[0-9]+}}* [[T_VAR1_REF]],
571
572// __kmpc_end_reduce_nowait(<loc>, <gtid>, &<lock>);
573// CHECK: call void @__kmpc_end_reduce_nowait(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]])
574
575// break;
576// CHECK: br label %[[RED_DONE]]
577
578// case 2:
579// t_var += t_var_reduction;
580// CHECK: [[T_VAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]]
581// CHECK: atomicrmw add i32* [[T_VAR_REF]], i32 [[T_VAR_PRIV_VAL]] monotonic
582
583// var = var.operator &(var_reduction);
584// CHECK: call void @__kmpc_critical(
585// CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_INT_TY]]* @{{.+}}([[S_INT_TY]]* [[VAR_REF]], [[S_INT_TY]]* dereferenceable(4) [[VAR_PRIV]])
586// CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR_REF]] to i8*
587// CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[UP]] to i8*
588// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
589// CHECK: call void @__kmpc_end_critical(
590
591// var1 = var1.operator &&(var1_reduction);
592// CHECK: call void @__kmpc_critical(
593// CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_REF]])
594// CHECK: [[VAR1_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0
Alexey Bataev69a47792015-05-07 03:54:03 +0000595// CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[END2:.+]]
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000596// CHECK: [[TRUE]]
597// CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_PRIV]])
598// CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000599// CHECK: br label %[[END2]]
600// CHECK: [[END2]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000601// CHECK: [[COND_LVALUE:%.+]] = phi i1 [ false, %{{.+}} ], [ [[VAR1_REDUCTION_BOOL]], %[[TRUE]] ]
602// CHECK: [[CONV:%.+]] = zext i1 [[COND_LVALUE]] to i32
603// CHECK: call void @{{.+}}([[S_INT_TY]]* [[COND_LVALUE:%.+]], i32 [[CONV]])
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000604// CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR1_REF]] to i8*
605// CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[COND_LVALUE]] to i8*
606// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
607// CHECK: call void @__kmpc_end_critical(
608
609// t_var1 = min(t_var1, t_var1_reduction);
610// CHECK: [[T_VAR1_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_PRIV]]
611// CHECK: atomicrmw min i32* [[T_VAR1_REF]], i32 [[T_VAR1_PRIV_VAL]] monotonic
612
613// break;
614// CHECK: br label %[[RED_DONE]]
615// CHECK: [[RED_DONE]]
616// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]])
617// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]*
618// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
619// CHECK: ret void
620
621// void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
622// *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]);
623// ...
624// *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1],
625// *(Type<n>-1*)rhs[<n>-1]);
626// }
627// CHECK: define internal void [[REDUCTION_FUNC]](i8*, i8*)
628// t_var_lhs = (i{{[0-9]+}}*)lhs[0];
629// CHECK: [[T_VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS:%.+]], i32 0, i32 0
630// CHECK: [[T_VAR_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR_RHS_REF]],
631// CHECK: [[T_VAR_RHS:%.+]] = bitcast i8* [[T_VAR_RHS_VOID]] to i{{[0-9]+}}*
632// t_var_rhs = (i{{[0-9]+}}*)rhs[0];
633// CHECK: [[T_VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS:%.+]], i32 0, i32 0
634// CHECK: [[T_VAR_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR_LHS_REF]],
635// CHECK: [[T_VAR_LHS:%.+]] = bitcast i8* [[T_VAR_LHS_VOID]] to i{{[0-9]+}}*
636
637// var_lhs = (S<i{{[0-9]+}}>*)lhs[1];
638// CHECK: [[VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 1
639// CHECK: [[VAR_RHS_VOID:%.+]] = load i8*, i8** [[VAR_RHS_REF]],
640// CHECK: [[VAR_RHS:%.+]] = bitcast i8* [[VAR_RHS_VOID]] to [[S_INT_TY]]*
641// var_rhs = (S<i{{[0-9]+}}>*)rhs[1];
642// CHECK: [[VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 1
643// CHECK: [[VAR_LHS_VOID:%.+]] = load i8*, i8** [[VAR_LHS_REF]],
644// CHECK: [[VAR_LHS:%.+]] = bitcast i8* [[VAR_LHS_VOID]] to [[S_INT_TY]]*
645
646// var1_lhs = (S<i{{[0-9]+}}>*)lhs[2];
647// CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 2
648// CHECK: [[VAR1_RHS_VOID:%.+]] = load i8*, i8** [[VAR1_RHS_REF]],
649// CHECK: [[VAR1_RHS:%.+]] = bitcast i8* [[VAR1_RHS_VOID]] to [[S_INT_TY]]*
650// var1_rhs = (S<i{{[0-9]+}}>*)rhs[2];
651// CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 2
652// CHECK: [[VAR1_LHS_VOID:%.+]] = load i8*, i8** [[VAR1_LHS_REF]],
653// CHECK: [[VAR1_LHS:%.+]] = bitcast i8* [[VAR1_LHS_VOID]] to [[S_INT_TY]]*
654
655// t_var1_lhs = (i{{[0-9]+}}*)lhs[3];
656// CHECK: [[T_VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 3
657// CHECK: [[T_VAR1_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_RHS_REF]],
658// CHECK: [[T_VAR1_RHS:%.+]] = bitcast i8* [[T_VAR1_RHS_VOID]] to i{{[0-9]+}}*
659// t_var1_rhs = (i{{[0-9]+}}*)rhs[3];
660// CHECK: [[T_VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 3
661// CHECK: [[T_VAR1_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_LHS_REF]],
662// CHECK: [[T_VAR1_LHS:%.+]] = bitcast i8* [[T_VAR1_LHS_VOID]] to i{{[0-9]+}}*
663
664// t_var_lhs += t_var_rhs;
665// CHECK: [[T_VAR_LHS_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_LHS]],
666// CHECK: [[T_VAR_RHS_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_RHS]],
667// CHECK: [[UP:%.+]] = add nsw i{{[0-9]+}} [[T_VAR_LHS_VAL]], [[T_VAR_RHS_VAL]]
668// CHECK: store i{{[0-9]+}} [[UP]], i{{[0-9]+}}* [[T_VAR_LHS]],
669
670// var_lhs = var_lhs.operator &(var_rhs);
671// CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_INT_TY]]* @{{.+}}([[S_INT_TY]]* [[VAR_LHS]], [[S_INT_TY]]* dereferenceable(4) [[VAR_RHS]])
672// CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR_LHS]] to i8*
673// CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[UP]] to i8*
674// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
675
676// var1_lhs = var1_lhs.operator &&(var1_rhs);
677// CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_LHS]])
678// CHECK: [[VAR1_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0
Alexey Bataev69a47792015-05-07 03:54:03 +0000679// CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[END2:.+]]
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000680// CHECK: [[TRUE]]
681// CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_RHS]])
682// CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000683// CHECK: br label %[[END2]]
684// CHECK: [[END2]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000685// CHECK: [[COND_LVALUE:%.+]] = phi i1 [ false, %{{.+}} ], [ [[VAR1_REDUCTION_BOOL]], %[[TRUE]] ]
686// CHECK: [[CONV:%.+]] = zext i1 [[COND_LVALUE]] to i32
687// CHECK: call void @{{.+}}([[S_INT_TY]]* [[COND_LVALUE:%.+]], i32 [[CONV]])
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000688// CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR1_LHS]] to i8*
689// CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[COND_LVALUE]] to i8*
690// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
691
692// t_var1_lhs = min(t_var1_lhs, t_var1_rhs);
693// CHECK: [[T_VAR1_LHS_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_LHS]],
694// CHECK: [[T_VAR1_RHS_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_RHS]],
695// CHECK: [[CMP:%.+]] = icmp slt i{{[0-9]+}} [[T_VAR1_LHS_VAL]], [[T_VAR1_RHS_VAL]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000696// CHECK: br i1 [[CMP]]
697// CHECK: [[UP:%.+]] = phi i32
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000698// CHECK: store i{{[0-9]+}} [[UP]], i{{[0-9]+}}* [[T_VAR1_LHS]],
699// CHECK: ret void
700
701#endif
702