blob: 16a2213655ecf8fbaac5cbd98809ab8c6a8b75f4 [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
Adrian Prantlbc068582015-07-08 01:00:30 +00007// REQUIRES: x86-registered-target
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +00008#ifndef HEADER
9#define HEADER
10
Alexey Bataevcaacd532015-09-04 11:26:21 +000011volatile double g, g_orig;
12volatile double &g1 = g_orig;
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +000013
14template <class T>
15struct S {
16 T f;
17 S(T a) : f(a + g) {}
18 S() : f(g) {}
19 operator T() { return T(); }
20 S &operator&(const S &) { return *this; }
21 ~S() {}
22};
23
24// CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float }
25// CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
26// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { float*, [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]*, float*, [2 x i{{[0-9]+}}]*, [2 x [[S_FLOAT_TY]]]* }
27// 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]]]* }
28// CHECK-DAG: [[ATOMIC_REDUCE_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 18, i32 0, i32 0, i8*
29// CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8*
30// CHECK-DAG: [[REDUCTION_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 18, i32 0, i32 0, i8*
31// CHECK-DAG: [[REDUCTION_LOCK:@.+]] = common global [8 x i32] zeroinitializer
32
33template <typename T>
34T tmain() {
35 T t;
36 S<T> test;
37 T t_var = T(), t_var1;
38 T vec[] = {1, 2};
39 S<T> s_arr[] = {1, 2};
Alexey Bataevcaacd532015-09-04 11:26:21 +000040 S<T> &var = test;
41 S<T> var1;
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +000042#pragma omp parallel
43#pragma omp for reduction(+:t_var) reduction(&:var) reduction(&& : var1) reduction(min: t_var1) nowait
44 for (int i = 0; i < 2; ++i) {
45 vec[i] = t_var;
46 s_arr[i] = var;
47 }
Alexey Bataev19fa2c32015-04-29 05:21:03 +000048#pragma omp parallel
49#pragma omp for reduction(&& : t_var)
50 for (int i = 0; i < 2; ++i) {
51 vec[i] = t_var;
52 s_arr[i] = var;
53 }
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +000054 return T();
55}
56
57int main() {
58#ifdef LAMBDA
59 // LAMBDA: [[G:@.+]] = global double
60 // LAMBDA-LABEL: @main
61 // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
62 [&]() {
63 // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
64 // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}})
65#pragma omp parallel
Alexey Bataevcaacd532015-09-04 11:26:21 +000066#pragma omp for reduction(+:g, g1)
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +000067 for (int i = 0; i < 2; ++i) {
68 // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* %{{.+}})
69 // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double,
70
71 // Reduction list for runtime.
Alexey Bataevcaacd532015-09-04 11:26:21 +000072 // LAMBDA: [[RED_LIST:%.+]] = alloca [2 x i8*],
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +000073
74 // LAMBDA: store double 0.0{{.+}}, double* [[G_PRIVATE_ADDR]]
75 // LAMBDA: call void @__kmpc_for_static_init_4(
76 g = 1;
Alexey Bataevcaacd532015-09-04 11:26:21 +000077 g1 = 1;
Alexey Bataevb44fdfc2015-07-14 10:32:29 +000078 // LAMBDA: store double 1.0{{.+}}, double* [[G_PRIVATE_ADDR]],
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +000079 // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
80 // LAMBDA: store double* [[G_PRIVATE_ADDR]], double** [[G_PRIVATE_ADDR_REF]]
81 // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
82 // LAMBDA: call void @__kmpc_for_static_fini(
83
Alexey Bataevcaacd532015-09-04 11:26:21 +000084 // LAMBDA: [[G_PRIV_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST]], i32 0, i32 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +000085 // LAMBDA: [[BITCAST:%.+]] = bitcast double* [[G_PRIVATE_ADDR]] to i8*
86 // LAMBDA: store i8* [[BITCAST]], i8** [[G_PRIV_REF]],
87 // LAMBDA: call i32 @__kmpc_reduce(
88 // LAMBDA: switch i32 %{{.+}}, label %[[REDUCTION_DONE:.+]] [
89 // LAMBDA: i32 1, label %[[CASE1:.+]]
90 // LAMBDA: i32 2, label %[[CASE2:.+]]
91 // LAMBDA: [[CASE1]]
92 // LAMBDA: [[G_VAL:%.+]] = load double, double* [[G]]
93 // LAMBDA: [[G_PRIV_VAL:%.+]] = load double, double* [[G_PRIVATE_ADDR]]
94 // LAMBDA: [[ADD:%.+]] = fadd double [[G_VAL]], [[G_PRIV_VAL]]
95 // LAMBDA: store double [[ADD]], double* [[G]]
96 // LAMBDA: call void @__kmpc_end_reduce(
97 // LAMBDA: br label %[[REDUCTION_DONE]]
98 // LAMBDA: [[CASE2]]
99 // LAMBDA: [[G_PRIV_VAL:%.+]] = load double, double* [[G_PRIVATE_ADDR]]
100 // LAMBDA: fadd double
101 // LAMBDA: cmpxchg i64*
Alexey Bataev69a47792015-05-07 03:54:03 +0000102 // LAMBDA: call void @__kmpc_end_reduce(
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000103 // LAMBDA: br label %[[REDUCTION_DONE]]
104 // LAMBDA: [[REDUCTION_DONE]]
105 // LAMBDA: ret void
106 [&]() {
107 // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
108 // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
109 g = 2;
Alexey Bataevcaacd532015-09-04 11:26:21 +0000110 g1 = 2;
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000111 // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
112 // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
113 // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]]
Alexey Bataevb44fdfc2015-07-14 10:32:29 +0000114 // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]]
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000115 }();
116 }
117 }();
118 return 0;
119#elif defined(BLOCKS)
120 // BLOCKS: [[G:@.+]] = global double
121 // BLOCKS-LABEL: @main
122 // BLOCKS: call void {{%.+}}(i8
123 ^{
124 // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
125 // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}})
126#pragma omp parallel
Alexey Bataevcaacd532015-09-04 11:26:21 +0000127#pragma omp for reduction(-:g, g1)
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000128 for (int i = 0; i < 2; ++i) {
129 // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* %{{.+}})
130 // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca double,
131
132 // Reduction list for runtime.
Alexey Bataevcaacd532015-09-04 11:26:21 +0000133 // BLOCKS: [[RED_LIST:%.+]] = alloca [2 x i8*],
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000134
135 // BLOCKS: store double 0.0{{.+}}, double* [[G_PRIVATE_ADDR]]
136 g = 1;
Alexey Bataevcaacd532015-09-04 11:26:21 +0000137 g1 = 1;
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000138 // BLOCKS: call void @__kmpc_for_static_init_4(
Alexey Bataevb44fdfc2015-07-14 10:32:29 +0000139 // BLOCKS: store double 1.0{{.+}}, double* [[G_PRIVATE_ADDR]],
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000140 // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
141 // BLOCKS: double* [[G_PRIVATE_ADDR]]
142 // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
143 // BLOCKS: call void {{%.+}}(i8
144 // BLOCKS: call void @__kmpc_for_static_fini(
145
Alexey Bataevcaacd532015-09-04 11:26:21 +0000146 // BLOCKS: [[G_PRIV_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST]], i32 0, i32 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000147 // BLOCKS: [[BITCAST:%.+]] = bitcast double* [[G_PRIVATE_ADDR]] to i8*
148 // BLOCKS: store i8* [[BITCAST]], i8** [[G_PRIV_REF]],
149 // BLOCKS: call i32 @__kmpc_reduce(
150 // BLOCKS: switch i32 %{{.+}}, label %[[REDUCTION_DONE:.+]] [
151 // BLOCKS: i32 1, label %[[CASE1:.+]]
152 // BLOCKS: i32 2, label %[[CASE2:.+]]
153 // BLOCKS: [[CASE1]]
154 // BLOCKS: [[G_VAL:%.+]] = load double, double* [[G]]
155 // BLOCKS: [[G_PRIV_VAL:%.+]] = load double, double* [[G_PRIVATE_ADDR]]
156 // BLOCKS: [[ADD:%.+]] = fadd double [[G_VAL]], [[G_PRIV_VAL]]
157 // BLOCKS: store double [[ADD]], double* [[G]]
158 // BLOCKS: call void @__kmpc_end_reduce(
159 // BLOCKS: br label %[[REDUCTION_DONE]]
160 // BLOCKS: [[CASE2]]
161 // BLOCKS: [[G_PRIV_VAL:%.+]] = load double, double* [[G_PRIVATE_ADDR]]
162 // BLOCKS: fadd double
163 // BLOCKS: cmpxchg i64*
Alexey Bataev69a47792015-05-07 03:54:03 +0000164 // BLOCKS: call void @__kmpc_end_reduce(
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000165 // BLOCKS: br label %[[REDUCTION_DONE]]
166 // BLOCKS: [[REDUCTION_DONE]]
167 // BLOCKS: ret void
168 ^{
169 // BLOCKS: define {{.+}} void {{@.+}}(i8*
170 g = 2;
Alexey Bataevcaacd532015-09-04 11:26:21 +0000171 g1 = 2;
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000172 // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
Alexey Bataevb44fdfc2015-07-14 10:32:29 +0000173 // BLOCKS: store double 2.0{{.+}}, double*
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000174 // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
175 // BLOCKS: ret
176 }();
177 }
178 }();
179 return 0;
180#else
181 S<float> test;
182 float t_var = 0, t_var1;
183 int vec[] = {1, 2};
184 S<float> s_arr[] = {1, 2};
Alexey Bataevcaacd532015-09-04 11:26:21 +0000185 S<float> &var = test;
186 S<float> var1;
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000187#pragma omp parallel
188#pragma omp for reduction(+:t_var) reduction(&:var) reduction(&& : var1) reduction(min: t_var1)
189 for (int i = 0; i < 2; ++i) {
190 vec[i] = t_var;
191 s_arr[i] = var;
192 }
193 return tmain<int>();
194#endif
195}
196
197// CHECK: define {{.*}}i{{[0-9]+}} @main()
198// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
199// CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
200// CHECK: %{{.+}} = bitcast [[CAP_MAIN_TY]]*
201// 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
202// CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]()
203// CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]*
204// CHECK: ret
205//
206// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_MAIN_TY]]* %{{.+}})
207// CHECK: [[T_VAR_PRIV:%.+]] = alloca float,
208// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
209// CHECK: [[VAR1_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
210// CHECK: [[T_VAR1_PRIV:%.+]] = alloca float,
211
212// Reduction list for runtime.
213// CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*],
214
215// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
216
217// CHECK: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}}
218// CHECK: [[T_VAR_REF:%.+]] = load float*, float** [[T_VAR_PTR_REF]],
219// For + reduction operation initial value of private variable is 0.
220// CHECK: store float 0.0{{.+}}, float* [[T_VAR_PRIV]],
221
222// CHECK: [[VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}}
223// CHECK: [[VAR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_PTR_REF:%.+]],
224// For & reduction operation initial value of private variable is ones in all bits.
225// CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
226
227// CHECK: [[VAR1_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}}
228// CHECK: [[VAR1_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[VAR_PTR_REF:%.+]],
229// For && reduction operation initial value of private variable is 1.0.
230// CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[VAR1_PRIV]])
231
232// CHECK: [[T_VAR1_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}}
233// CHECK: [[T_VAR1_REF:%.+]] = load float*, float** [[T_VAR1_PTR_REF]],
234// For min reduction operation initial value of private variable is largest repesentable value.
235// CHECK: store float 0x47EFFFFFE0000000, float* [[T_VAR1_PRIV]],
236
237
238// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
239// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
240// CHECK: call void @__kmpc_for_static_init_4(
241// Skip checks for internal operations.
242// CHECK: call void @__kmpc_for_static_fini(
243
244// void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
245
246// CHECK: [[T_VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 0
247// CHECK: [[BITCAST:%.+]] = bitcast float* [[T_VAR_PRIV]] to i8*
248// CHECK: store i8* [[BITCAST]], i8** [[T_VAR_PRIV_REF]],
249// CHECK: [[VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 1
250// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_PRIV]] to i8*
251// CHECK: store i8* [[BITCAST]], i8** [[VAR_PRIV_REF]],
252// CHECK: [[VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 2
253// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR1_PRIV]] to i8*
254// CHECK: store i8* [[BITCAST]], i8** [[VAR1_PRIV_REF]],
255// CHECK: [[T_VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 3
256// CHECK: [[BITCAST:%.+]] = bitcast float* [[T_VAR1_PRIV]] to i8*
257// CHECK: store i8* [[BITCAST]], i8** [[T_VAR1_PRIV_REF]],
258
259// res = __kmpc_reduce(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>);
260
261// CHECK: [[BITCAST:%.+]] = bitcast [4 x i8*]* [[RED_LIST]] to i8*
262// 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]])
263
264// switch(res)
265// CHECK: switch i32 [[RES]], label %[[RED_DONE:.+]] [
266// CHECK: i32 1, label %[[CASE1:.+]]
267// CHECK: i32 2, label %[[CASE2:.+]]
268// CHECK: ]
269
270// case 1:
271// t_var += t_var_reduction;
272// CHECK: [[T_VAR_VAL:%.+]] = load float, float* [[T_VAR_REF]],
273// CHECK: [[T_VAR_PRIV_VAL:%.+]] = load float, float* [[T_VAR_PRIV]],
274// CHECK: [[UP:%.+]] = fadd float [[T_VAR_VAL]], [[T_VAR_PRIV_VAL]]
275// CHECK: store float [[UP]], float* [[T_VAR_REF]],
276
277// var = var.operator &(var_reduction);
278// CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_FLOAT_TY]]* @{{.+}}([[S_FLOAT_TY]]* [[VAR_REF]], [[S_FLOAT_TY]]* dereferenceable(4) [[VAR_PRIV]])
279// CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_REF]] to i8*
280// CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[UP]] to i8*
281// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
282
283// var1 = var1.operator &&(var1_reduction);
284// CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_REF]])
285// CHECK: [[VAR1_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0
Alexey Bataev69a47792015-05-07 03:54:03 +0000286// CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[END2:.+]]
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000287// CHECK: [[TRUE]]
288// CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_PRIV]])
289// CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000290// CHECK: br label %[[END2]]
291// CHECK: [[END2]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000292// CHECK: [[COND_LVALUE:%.+]] = phi i1 [ false, %{{.+}} ], [ [[VAR1_REDUCTION_BOOL]], %[[TRUE]] ]
293// CHECK: [[CONV:%.+]] = uitofp i1 [[COND_LVALUE]] to float
294// CHECK: call void @{{.+}}([[S_FLOAT_TY]]* [[COND_LVALUE:%.+]], float [[CONV]])
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000295// CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR1_REF]] to i8*
296// CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[COND_LVALUE]] to i8*
297// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
298
299// t_var1 = min(t_var1, t_var1_reduction);
300// CHECK: [[T_VAR1_VAL:%.+]] = load float, float* [[T_VAR1_REF]],
301// CHECK: [[T_VAR1_PRIV_VAL:%.+]] = load float, float* [[T_VAR1_PRIV]],
302// CHECK: [[CMP:%.+]] = fcmp olt float [[T_VAR1_VAL]], [[T_VAR1_PRIV_VAL]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000303// CHECK: br i1 [[CMP]]
304// CHECK: [[UP:%.+]] = phi float
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000305// CHECK: store float [[UP]], float* [[T_VAR1_REF]],
306
307// __kmpc_end_reduce(<loc>, <gtid>, &<lock>);
308// CHECK: call void @__kmpc_end_reduce(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]])
309
310// break;
311// CHECK: br label %[[RED_DONE]]
312
313// case 2:
314// t_var += t_var_reduction;
315// CHECK: load float, float* [[T_VAR_PRIV]]
316// CHECK: [[T_VAR_REF_INT:%.+]] = bitcast float* [[T_VAR_REF]] to i32*
Alexey Bataevf0ab5532015-05-15 08:36:34 +0000317// CHECK: [[OLD1:%.+]] = load atomic i32, i32* [[T_VAR_REF_INT]] monotonic,
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000318// CHECK: br label %[[CONT:.+]]
319// CHECK: [[CONT]]
Alexey Bataevf0ab5532015-05-15 08:36:34 +0000320// CHECK: [[ORIG_OLD_INT:%.+]] = phi i32 [ [[OLD1]], %{{.+}} ], [ [[OLD2:%.+]], %[[CONT]] ]
321// CHECK: fadd float
322// CHECK: [[UP_INT:%.+]] = load i32, i32*
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000323// CHECK: [[T_VAR_REF_INT:%.+]] = bitcast float* [[T_VAR_REF]] to i32*
324// CHECK: [[RES:%.+]] = cmpxchg i32* [[T_VAR_REF_INT]], i32 [[ORIG_OLD_INT]], i32 [[UP_INT]] monotonic monotonic
Alexey Bataevf0ab5532015-05-15 08:36:34 +0000325// CHECK: [[OLD2:%.+]] = extractvalue { i32, i1 } [[RES]], 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000326// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i32, i1 } [[RES]], 1
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000327// CHECK: br i1 [[SUCCESS_FAIL]], label %[[ATOMIC_DONE:.+]], label %[[CONT]]
328// CHECK: [[ATOMIC_DONE]]
329
330// var = var.operator &(var_reduction);
331// CHECK: call void @__kmpc_critical(
332// CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_FLOAT_TY]]* @{{.+}}([[S_FLOAT_TY]]* [[VAR_REF]], [[S_FLOAT_TY]]* dereferenceable(4) [[VAR_PRIV]])
333// CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_REF]] to i8*
334// CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[UP]] to i8*
335// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
336// CHECK: call void @__kmpc_end_critical(
337
338// var1 = var1.operator &&(var1_reduction);
339// CHECK: call void @__kmpc_critical(
340// CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_REF]])
341// CHECK: [[VAR1_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0
Alexey Bataev69a47792015-05-07 03:54:03 +0000342// CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[END2:.+]]
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000343// CHECK: [[TRUE]]
344// CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_PRIV]])
345// CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000346// CHECK: br label %[[END2]]
347// CHECK: [[END2]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000348// CHECK: [[COND_LVALUE:%.+]] = phi i1 [ false, %{{.+}} ], [ [[VAR1_REDUCTION_BOOL]], %[[TRUE]] ]
349// CHECK: [[CONV:%.+]] = uitofp i1 [[COND_LVALUE]] to float
350// CHECK: call void @{{.+}}([[S_FLOAT_TY]]* [[COND_LVALUE:%.+]], float [[CONV]])
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000351// CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR1_REF]] to i8*
352// CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[COND_LVALUE]] to i8*
353// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
354// CHECK: call void @__kmpc_end_critical(
355
356// t_var1 = min(t_var1, t_var1_reduction);
357// CHECK: load float, float* [[T_VAR1_PRIV]]
358// CHECK: [[T_VAR1_REF_INT:%.+]] = bitcast float* [[T_VAR1_REF]] to i32*
Alexey Bataevf0ab5532015-05-15 08:36:34 +0000359// CHECK: [[OLD1:%.+]] = load atomic i32, i32* [[T_VAR1_REF_INT]] monotonic,
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000360// CHECK: br label %[[CONT:.+]]
361// CHECK: [[CONT]]
Alexey Bataevf0ab5532015-05-15 08:36:34 +0000362// CHECK: [[ORIG_OLD_INT:%.+]] = phi i32 [ [[OLD1]], %{{.+}} ], [ [[OLD2:%.+]], %{{.+}} ]
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000363// CHECK: [[CMP:%.+]] = fcmp olt float
Alexey Bataev69a47792015-05-07 03:54:03 +0000364// CHECK: br i1 [[CMP]]
Alexey Bataevf0ab5532015-05-15 08:36:34 +0000365// CHECK: phi float
366// CHECK: [[UP_INT:%.+]] = load i32
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000367// CHECK: [[T_VAR1_REF_INT:%.+]] = bitcast float* [[T_VAR1_REF]] to i32*
368// CHECK: [[RES:%.+]] = cmpxchg i32* [[T_VAR1_REF_INT]], i32 [[ORIG_OLD_INT]], i32 [[UP_INT]] monotonic monotonic
Alexey Bataevf0ab5532015-05-15 08:36:34 +0000369// CHECK: [[OLD2:%.+]] = extractvalue { i32, i1 } [[RES]], 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000370// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i32, i1 } [[RES]], 1
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000371// CHECK: br i1 [[SUCCESS_FAIL]], label %[[ATOMIC_DONE:.+]], label %[[CONT]]
372// CHECK: [[ATOMIC_DONE]]
373
Alexey Bataev69a47792015-05-07 03:54:03 +0000374// __kmpc_end_reduce(<loc>, <gtid>, &<lock>);
375// CHECK: call void @__kmpc_end_reduce(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]])
376
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000377// break;
378// CHECK: br label %[[RED_DONE]]
379// CHECK: [[RED_DONE]]
380// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
381// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]*
382// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
383// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
384
385// CHECK: ret void
386
387// void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
388// *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]);
389// ...
390// *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1],
391// *(Type<n>-1*)rhs[<n>-1]);
392// }
393// CHECK: define internal void [[REDUCTION_FUNC]](i8*, i8*)
394// t_var_lhs = (float*)lhs[0];
395// CHECK: [[T_VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS:%.+]], i32 0, i32 0
396// CHECK: [[T_VAR_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR_RHS_REF]],
397// CHECK: [[T_VAR_RHS:%.+]] = bitcast i8* [[T_VAR_RHS_VOID]] to float*
398// t_var_rhs = (float*)rhs[0];
399// CHECK: [[T_VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS:%.+]], i32 0, i32 0
400// CHECK: [[T_VAR_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR_LHS_REF]],
401// CHECK: [[T_VAR_LHS:%.+]] = bitcast i8* [[T_VAR_LHS_VOID]] to float*
402
403// var_lhs = (S<float>*)lhs[1];
404// CHECK: [[VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 1
405// CHECK: [[VAR_RHS_VOID:%.+]] = load i8*, i8** [[VAR_RHS_REF]],
406// CHECK: [[VAR_RHS:%.+]] = bitcast i8* [[VAR_RHS_VOID]] to [[S_FLOAT_TY]]*
407// var_rhs = (S<float>*)rhs[1];
408// CHECK: [[VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 1
409// CHECK: [[VAR_LHS_VOID:%.+]] = load i8*, i8** [[VAR_LHS_REF]],
410// CHECK: [[VAR_LHS:%.+]] = bitcast i8* [[VAR_LHS_VOID]] to [[S_FLOAT_TY]]*
411
412// var1_lhs = (S<float>*)lhs[2];
413// CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 2
414// CHECK: [[VAR1_RHS_VOID:%.+]] = load i8*, i8** [[VAR1_RHS_REF]],
415// CHECK: [[VAR1_RHS:%.+]] = bitcast i8* [[VAR1_RHS_VOID]] to [[S_FLOAT_TY]]*
416// var1_rhs = (S<float>*)rhs[2];
417// CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 2
418// CHECK: [[VAR1_LHS_VOID:%.+]] = load i8*, i8** [[VAR1_LHS_REF]],
419// CHECK: [[VAR1_LHS:%.+]] = bitcast i8* [[VAR1_LHS_VOID]] to [[S_FLOAT_TY]]*
420
421// t_var1_lhs = (float*)lhs[3];
422// CHECK: [[T_VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 3
423// CHECK: [[T_VAR1_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_RHS_REF]],
424// CHECK: [[T_VAR1_RHS:%.+]] = bitcast i8* [[T_VAR1_RHS_VOID]] to float*
425// t_var1_rhs = (float*)rhs[3];
426// CHECK: [[T_VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 3
427// CHECK: [[T_VAR1_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_LHS_REF]],
428// CHECK: [[T_VAR1_LHS:%.+]] = bitcast i8* [[T_VAR1_LHS_VOID]] to float*
429
430// t_var_lhs += t_var_rhs;
431// CHECK: [[T_VAR_LHS_VAL:%.+]] = load float, float* [[T_VAR_LHS]],
432// CHECK: [[T_VAR_RHS_VAL:%.+]] = load float, float* [[T_VAR_RHS]],
433// CHECK: [[UP:%.+]] = fadd float [[T_VAR_LHS_VAL]], [[T_VAR_RHS_VAL]]
434// CHECK: store float [[UP]], float* [[T_VAR_LHS]],
435
436// var_lhs = var_lhs.operator &(var_rhs);
437// CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_FLOAT_TY]]* @{{.+}}([[S_FLOAT_TY]]* [[VAR_LHS]], [[S_FLOAT_TY]]* dereferenceable(4) [[VAR_RHS]])
438// CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_LHS]] to i8*
439// CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[UP]] to i8*
440// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
441
442// var1_lhs = var1_lhs.operator &&(var1_rhs);
443// CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_LHS]])
444// CHECK: [[VAR1_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0
Alexey Bataev69a47792015-05-07 03:54:03 +0000445// CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[END2:.+]]
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000446// CHECK: [[TRUE]]
447// CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_RHS]])
448// CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000449// CHECK: br label %[[END2]]
450// CHECK: [[END2]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000451// CHECK: [[COND_LVALUE:%.+]] = phi i1 [ false, %{{.+}} ], [ [[VAR1_REDUCTION_BOOL]], %[[TRUE]] ]
452// CHECK: [[CONV:%.+]] = uitofp i1 [[COND_LVALUE]] to float
453// CHECK: call void @{{.+}}([[S_FLOAT_TY]]* [[COND_LVALUE:%.+]], float [[CONV]])
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000454// CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR1_LHS]] to i8*
455// CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[COND_LVALUE]] to i8*
456// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
457
458// t_var1_lhs = min(t_var1_lhs, t_var1_rhs);
459// CHECK: [[T_VAR1_LHS_VAL:%.+]] = load float, float* [[T_VAR1_LHS]],
460// CHECK: [[T_VAR1_RHS_VAL:%.+]] = load float, float* [[T_VAR1_RHS]],
461// CHECK: [[CMP:%.+]] = fcmp olt float [[T_VAR1_LHS_VAL]], [[T_VAR1_RHS_VAL]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000462// CHECK: br i1 [[CMP]]
463// CHECK: [[UP:%.+]] = phi float
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000464// CHECK: store float [[UP]], float* [[T_VAR1_LHS]],
465// CHECK: ret void
466
467// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
468// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
469// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
470// CHECK: %{{.+}} = bitcast [[CAP_TMAIN_TY]]*
471// 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
472// CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
473// CHECK: ret
474//
475// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* [[GTID_ADDR:%.+]], i{{[0-9]+}}* %{{.+}}, [[CAP_TMAIN_TY]]* %{{.+}})
476// CHECK: alloca i{{[0-9]+}},
477// CHECK: alloca i{{[0-9]+}},
478// CHECK: alloca i{{[0-9]+}},
479// CHECK: alloca i{{[0-9]+}},
480// CHECK: alloca i{{[0-9]+}},
481// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
482// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
483// CHECK: [[VAR1_PRIV:%.+]] = alloca [[S_INT_TY]],
484// CHECK: [[T_VAR1_PRIV:%.+]] = alloca i{{[0-9]+}},
485
486// Reduction list for runtime.
487// CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*],
488
489// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
490
491// CHECK: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}}
492// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_PTR_REF]],
493// For + reduction operation initial value of private variable is 0.
494// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[T_VAR_PRIV]],
495
496// CHECK: [[VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}}
497// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_PTR_REF:%.+]],
498// For & reduction operation initial value of private variable is ones in all bits.
499// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[VAR_PRIV]])
500
501// CHECK: [[VAR1_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}}
502// CHECK: [[VAR1_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** [[VAR_PTR_REF:%.+]],
503// For && reduction operation initial value of private variable is 1.0.
504// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[VAR1_PRIV]])
505
506// CHECK: [[T_VAR1_PTR_REF:%.+]] = getelementptr inbounds [[CAP_TMAIN_TY]], [[CAP_TMAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} {{[0-9]+}}
507// CHECK: [[T_VAR1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR1_PTR_REF]],
508// For min reduction operation initial value of private variable is largest repesentable value.
509// CHECK: store i{{[0-9]+}} 2147483647, i{{[0-9]+}}* [[T_VAR1_PRIV]],
510
511// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
512// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
513// CHECK: call void @__kmpc_for_static_init_4(
514// Skip checks for internal operations.
515// CHECK: call void @__kmpc_for_static_fini(
516
517// void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
518
519// CHECK: [[T_VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 0
520// CHECK: [[BITCAST:%.+]] = bitcast i{{[0-9]+}}* [[T_VAR_PRIV]] to i8*
521// CHECK: store i8* [[BITCAST]], i8** [[T_VAR_PRIV_REF]],
522// CHECK: [[VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 1
523// CHECK: [[BITCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR_PRIV]] to i8*
524// CHECK: store i8* [[BITCAST]], i8** [[VAR_PRIV_REF]],
525// CHECK: [[VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 2
526// CHECK: [[BITCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR1_PRIV]] to i8*
527// CHECK: store i8* [[BITCAST]], i8** [[VAR1_PRIV_REF]],
528// CHECK: [[T_VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i32 0, i32 3
529// CHECK: [[BITCAST:%.+]] = bitcast i{{[0-9]+}}* [[T_VAR1_PRIV]] to i8*
530// CHECK: store i8* [[BITCAST]], i8** [[T_VAR1_PRIV_REF]],
531
532// res = __kmpc_reduce_nowait(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>);
533
534// CHECK: [[BITCAST:%.+]] = bitcast [4 x i8*]* [[RED_LIST]] to i8*
535// 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]])
536
537// switch(res)
538// CHECK: switch i32 [[RES]], label %[[RED_DONE:.+]] [
539// CHECK: i32 1, label %[[CASE1:.+]]
540// CHECK: i32 2, label %[[CASE2:.+]]
541// CHECK: ]
542
543// case 1:
544// t_var += t_var_reduction;
545// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]],
546// CHECK: [[T_VAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
547// CHECK: [[UP:%.+]] = add nsw i{{[0-9]+}} [[T_VAR_VAL]], [[T_VAR_PRIV_VAL]]
548// CHECK: store i{{[0-9]+}} [[UP]], i{{[0-9]+}}* [[T_VAR_REF]],
549
550// var = var.operator &(var_reduction);
551// CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_INT_TY]]* @{{.+}}([[S_INT_TY]]* [[VAR_REF]], [[S_INT_TY]]* dereferenceable(4) [[VAR_PRIV]])
552// CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR_REF]] to i8*
553// CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[UP]] to i8*
554// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
555
556// var1 = var1.operator &&(var1_reduction);
557// CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_REF]])
558// CHECK: [[VAR1_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0
Alexey Bataev69a47792015-05-07 03:54:03 +0000559// CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[END2:.+]]
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000560// CHECK: [[TRUE]]
561// CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_PRIV]])
562// CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000563// CHECK: br label %[[END2]]
564// CHECK: [[END2]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000565// CHECK: [[COND_LVALUE:%.+]] = phi i1 [ false, %{{.+}} ], [ [[VAR1_REDUCTION_BOOL]], %[[TRUE]] ]
566// CHECK: [[CONV:%.+]] = zext i1 [[COND_LVALUE]] to i32
567// CHECK: call void @{{.+}}([[S_INT_TY]]* [[COND_LVALUE:%.+]], i32 [[CONV]])
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000568// CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR1_REF]] to i8*
569// CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[COND_LVALUE]] to i8*
570// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
571
572// t_var1 = min(t_var1, t_var1_reduction);
573// CHECK: [[T_VAR1_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_REF]],
574// CHECK: [[T_VAR1_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_PRIV]],
575// CHECK: [[CMP:%.+]] = icmp slt i{{[0-9]+}} [[T_VAR1_VAL]], [[T_VAR1_PRIV_VAL]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000576// CHECK: br i1 [[CMP]]
577// CHECK: [[UP:%.+]] = phi i32
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000578// CHECK: store i{{[0-9]+}} [[UP]], i{{[0-9]+}}* [[T_VAR1_REF]],
579
580// __kmpc_end_reduce_nowait(<loc>, <gtid>, &<lock>);
581// CHECK: call void @__kmpc_end_reduce_nowait(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]])
582
583// break;
584// CHECK: br label %[[RED_DONE]]
585
586// case 2:
587// t_var += t_var_reduction;
588// CHECK: [[T_VAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]]
589// CHECK: atomicrmw add i32* [[T_VAR_REF]], i32 [[T_VAR_PRIV_VAL]] monotonic
590
591// var = var.operator &(var_reduction);
592// CHECK: call void @__kmpc_critical(
593// CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_INT_TY]]* @{{.+}}([[S_INT_TY]]* [[VAR_REF]], [[S_INT_TY]]* dereferenceable(4) [[VAR_PRIV]])
594// CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR_REF]] to i8*
595// CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[UP]] to i8*
596// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
597// CHECK: call void @__kmpc_end_critical(
598
599// var1 = var1.operator &&(var1_reduction);
600// CHECK: call void @__kmpc_critical(
601// CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_REF]])
602// CHECK: [[VAR1_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0
Alexey Bataev69a47792015-05-07 03:54:03 +0000603// CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[END2:.+]]
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000604// CHECK: [[TRUE]]
605// CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_PRIV]])
606// CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000607// CHECK: br label %[[END2]]
608// CHECK: [[END2]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000609// CHECK: [[COND_LVALUE:%.+]] = phi i1 [ false, %{{.+}} ], [ [[VAR1_REDUCTION_BOOL]], %[[TRUE]] ]
610// CHECK: [[CONV:%.+]] = zext i1 [[COND_LVALUE]] to i32
611// CHECK: call void @{{.+}}([[S_INT_TY]]* [[COND_LVALUE:%.+]], i32 [[CONV]])
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000612// CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR1_REF]] to i8*
613// CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[COND_LVALUE]] to i8*
614// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
615// CHECK: call void @__kmpc_end_critical(
616
617// t_var1 = min(t_var1, t_var1_reduction);
618// CHECK: [[T_VAR1_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_PRIV]]
619// CHECK: atomicrmw min i32* [[T_VAR1_REF]], i32 [[T_VAR1_PRIV_VAL]] monotonic
620
621// break;
622// CHECK: br label %[[RED_DONE]]
623// CHECK: [[RED_DONE]]
624// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]])
625// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]*
626// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
627// CHECK: ret void
628
629// void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
630// *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]);
631// ...
632// *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1],
633// *(Type<n>-1*)rhs[<n>-1]);
634// }
635// CHECK: define internal void [[REDUCTION_FUNC]](i8*, i8*)
636// t_var_lhs = (i{{[0-9]+}}*)lhs[0];
637// CHECK: [[T_VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS:%.+]], i32 0, i32 0
638// CHECK: [[T_VAR_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR_RHS_REF]],
639// CHECK: [[T_VAR_RHS:%.+]] = bitcast i8* [[T_VAR_RHS_VOID]] to i{{[0-9]+}}*
640// t_var_rhs = (i{{[0-9]+}}*)rhs[0];
641// CHECK: [[T_VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS:%.+]], i32 0, i32 0
642// CHECK: [[T_VAR_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR_LHS_REF]],
643// CHECK: [[T_VAR_LHS:%.+]] = bitcast i8* [[T_VAR_LHS_VOID]] to i{{[0-9]+}}*
644
645// var_lhs = (S<i{{[0-9]+}}>*)lhs[1];
646// CHECK: [[VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 1
647// CHECK: [[VAR_RHS_VOID:%.+]] = load i8*, i8** [[VAR_RHS_REF]],
648// CHECK: [[VAR_RHS:%.+]] = bitcast i8* [[VAR_RHS_VOID]] to [[S_INT_TY]]*
649// var_rhs = (S<i{{[0-9]+}}>*)rhs[1];
650// CHECK: [[VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 1
651// CHECK: [[VAR_LHS_VOID:%.+]] = load i8*, i8** [[VAR_LHS_REF]],
652// CHECK: [[VAR_LHS:%.+]] = bitcast i8* [[VAR_LHS_VOID]] to [[S_INT_TY]]*
653
654// var1_lhs = (S<i{{[0-9]+}}>*)lhs[2];
655// CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 2
656// CHECK: [[VAR1_RHS_VOID:%.+]] = load i8*, i8** [[VAR1_RHS_REF]],
657// CHECK: [[VAR1_RHS:%.+]] = bitcast i8* [[VAR1_RHS_VOID]] to [[S_INT_TY]]*
658// var1_rhs = (S<i{{[0-9]+}}>*)rhs[2];
659// CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 2
660// CHECK: [[VAR1_LHS_VOID:%.+]] = load i8*, i8** [[VAR1_LHS_REF]],
661// CHECK: [[VAR1_LHS:%.+]] = bitcast i8* [[VAR1_LHS_VOID]] to [[S_INT_TY]]*
662
663// t_var1_lhs = (i{{[0-9]+}}*)lhs[3];
664// CHECK: [[T_VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i32 0, i32 3
665// CHECK: [[T_VAR1_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_RHS_REF]],
666// CHECK: [[T_VAR1_RHS:%.+]] = bitcast i8* [[T_VAR1_RHS_VOID]] to i{{[0-9]+}}*
667// t_var1_rhs = (i{{[0-9]+}}*)rhs[3];
668// CHECK: [[T_VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i32 0, i32 3
669// CHECK: [[T_VAR1_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_LHS_REF]],
670// CHECK: [[T_VAR1_LHS:%.+]] = bitcast i8* [[T_VAR1_LHS_VOID]] to i{{[0-9]+}}*
671
672// t_var_lhs += t_var_rhs;
673// CHECK: [[T_VAR_LHS_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_LHS]],
674// CHECK: [[T_VAR_RHS_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_RHS]],
675// CHECK: [[UP:%.+]] = add nsw i{{[0-9]+}} [[T_VAR_LHS_VAL]], [[T_VAR_RHS_VAL]]
676// CHECK: store i{{[0-9]+}} [[UP]], i{{[0-9]+}}* [[T_VAR_LHS]],
677
678// var_lhs = var_lhs.operator &(var_rhs);
679// CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_INT_TY]]* @{{.+}}([[S_INT_TY]]* [[VAR_LHS]], [[S_INT_TY]]* dereferenceable(4) [[VAR_RHS]])
680// CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR_LHS]] to i8*
681// CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[UP]] to i8*
682// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
683
684// var1_lhs = var1_lhs.operator &&(var1_rhs);
685// CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_LHS]])
686// CHECK: [[VAR1_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0
Alexey Bataev69a47792015-05-07 03:54:03 +0000687// CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[END2:.+]]
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000688// CHECK: [[TRUE]]
689// CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_RHS]])
690// CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000691// CHECK: br label %[[END2]]
692// CHECK: [[END2]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000693// CHECK: [[COND_LVALUE:%.+]] = phi i1 [ false, %{{.+}} ], [ [[VAR1_REDUCTION_BOOL]], %[[TRUE]] ]
694// CHECK: [[CONV:%.+]] = zext i1 [[COND_LVALUE]] to i32
695// CHECK: call void @{{.+}}([[S_INT_TY]]* [[COND_LVALUE:%.+]], i32 [[CONV]])
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000696// CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR1_LHS]] to i8*
697// CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[COND_LVALUE]] to i8*
698// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
699
700// t_var1_lhs = min(t_var1_lhs, t_var1_rhs);
701// CHECK: [[T_VAR1_LHS_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_LHS]],
702// CHECK: [[T_VAR1_RHS_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_RHS]],
703// CHECK: [[CMP:%.+]] = icmp slt i{{[0-9]+}} [[T_VAR1_LHS_VAL]], [[T_VAR1_RHS_VAL]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000704// CHECK: br i1 [[CMP]]
705// CHECK: [[UP:%.+]] = phi i32
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000706// CHECK: store i{{[0-9]+}} [[UP]], i{{[0-9]+}}* [[T_VAR1_LHS]],
707// CHECK: ret void
708
709#endif
710