blob: 8535741c3338815389511ceae7b5b1d4ab5532a1 [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]+}} }
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +000026// 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};
Alexey Bataevcaacd532015-09-04 11:26:21 +000038 S<T> &var = test;
39 S<T> var1;
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +000040#pragma omp parallel
41#pragma omp for reduction(+:t_var) reduction(&:var) reduction(&& : var1) reduction(min: t_var1) nowait
42 for (int i = 0; i < 2; ++i) {
43 vec[i] = t_var;
44 s_arr[i] = var;
45 }
Alexey Bataev19fa2c32015-04-29 05:21:03 +000046#pragma omp parallel
47#pragma omp for reduction(&& : t_var)
48 for (int i = 0; i < 2; ++i) {
49 vec[i] = t_var;
50 s_arr[i] = var;
51 }
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +000052 return T();
53}
54
55int main() {
56#ifdef LAMBDA
57 // LAMBDA: [[G:@.+]] = global double
58 // LAMBDA-LABEL: @main
59 // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
60 [&]() {
61 // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
Alexey Bataev2377fe92015-09-10 08:12:02 +000062 // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, {{.+}}* [[OMP_REGION:@.+]] to {{.+}})
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +000063#pragma omp parallel
Alexey Bataevcaacd532015-09-04 11:26:21 +000064#pragma omp for reduction(+:g, g1)
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +000065 for (int i = 0; i < 2; ++i) {
Alexey Bataev2377fe92015-09-10 08:12:02 +000066 // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}})
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +000067 // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double,
68
69 // Reduction list for runtime.
Alexey Bataevcaacd532015-09-04 11:26:21 +000070 // LAMBDA: [[RED_LIST:%.+]] = alloca [2 x i8*],
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +000071
72 // LAMBDA: store double 0.0{{.+}}, double* [[G_PRIVATE_ADDR]]
73 // LAMBDA: call void @__kmpc_for_static_init_4(
74 g = 1;
Alexey Bataevcaacd532015-09-04 11:26:21 +000075 g1 = 1;
Alexey Bataevb44fdfc2015-07-14 10:32:29 +000076 // LAMBDA: store double 1.0{{.+}}, double* [[G_PRIVATE_ADDR]],
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +000077 // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
78 // LAMBDA: store double* [[G_PRIVATE_ADDR]], double** [[G_PRIVATE_ADDR_REF]]
79 // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
80 // LAMBDA: call void @__kmpc_for_static_fini(
81
John McCall7f416cc2015-09-08 08:05:57 +000082 // LAMBDA: [[G_PRIV_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST]], i64 0, i64 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +000083 // LAMBDA: [[BITCAST:%.+]] = bitcast double* [[G_PRIVATE_ADDR]] to i8*
84 // LAMBDA: store i8* [[BITCAST]], i8** [[G_PRIV_REF]],
85 // LAMBDA: call i32 @__kmpc_reduce(
86 // LAMBDA: switch i32 %{{.+}}, label %[[REDUCTION_DONE:.+]] [
87 // LAMBDA: i32 1, label %[[CASE1:.+]]
88 // LAMBDA: i32 2, label %[[CASE2:.+]]
89 // LAMBDA: [[CASE1]]
90 // LAMBDA: [[G_VAL:%.+]] = load double, double* [[G]]
91 // LAMBDA: [[G_PRIV_VAL:%.+]] = load double, double* [[G_PRIVATE_ADDR]]
92 // LAMBDA: [[ADD:%.+]] = fadd double [[G_VAL]], [[G_PRIV_VAL]]
93 // LAMBDA: store double [[ADD]], double* [[G]]
94 // LAMBDA: call void @__kmpc_end_reduce(
95 // LAMBDA: br label %[[REDUCTION_DONE]]
96 // LAMBDA: [[CASE2]]
97 // LAMBDA: [[G_PRIV_VAL:%.+]] = load double, double* [[G_PRIVATE_ADDR]]
98 // LAMBDA: fadd double
99 // LAMBDA: cmpxchg i64*
Alexey Bataev69a47792015-05-07 03:54:03 +0000100 // LAMBDA: call void @__kmpc_end_reduce(
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000101 // LAMBDA: br label %[[REDUCTION_DONE]]
102 // LAMBDA: [[REDUCTION_DONE]]
103 // LAMBDA: ret void
104 [&]() {
105 // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
106 // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
107 g = 2;
Alexey Bataevcaacd532015-09-04 11:26:21 +0000108 g1 = 2;
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000109 // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]]
110 // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
111 // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]]
Alexey Bataevb44fdfc2015-07-14 10:32:29 +0000112 // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]]
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000113 }();
114 }
115 }();
116 return 0;
117#elif defined(BLOCKS)
118 // BLOCKS: [[G:@.+]] = global double
119 // BLOCKS-LABEL: @main
120 // BLOCKS: call void {{%.+}}(i8
121 ^{
122 // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
Alexey Bataev2377fe92015-09-10 08:12:02 +0000123 // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 0, {{.+}}* [[OMP_REGION:@.+]] to {{.+}})
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000124#pragma omp parallel
Alexey Bataevcaacd532015-09-04 11:26:21 +0000125#pragma omp for reduction(-:g, g1)
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000126 for (int i = 0; i < 2; ++i) {
Alexey Bataev2377fe92015-09-10 08:12:02 +0000127 // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}})
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000128 // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca double,
129
130 // Reduction list for runtime.
Alexey Bataevcaacd532015-09-04 11:26:21 +0000131 // BLOCKS: [[RED_LIST:%.+]] = alloca [2 x i8*],
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000132
133 // BLOCKS: store double 0.0{{.+}}, double* [[G_PRIVATE_ADDR]]
134 g = 1;
Alexey Bataevcaacd532015-09-04 11:26:21 +0000135 g1 = 1;
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000136 // BLOCKS: call void @__kmpc_for_static_init_4(
Alexey Bataevb44fdfc2015-07-14 10:32:29 +0000137 // BLOCKS: store double 1.0{{.+}}, double* [[G_PRIVATE_ADDR]],
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000138 // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
139 // BLOCKS: double* [[G_PRIVATE_ADDR]]
140 // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
141 // BLOCKS: call void {{%.+}}(i8
142 // BLOCKS: call void @__kmpc_for_static_fini(
143
John McCall7f416cc2015-09-08 08:05:57 +0000144 // BLOCKS: [[G_PRIV_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST]], i64 0, i64 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000145 // BLOCKS: [[BITCAST:%.+]] = bitcast double* [[G_PRIVATE_ADDR]] to i8*
146 // BLOCKS: store i8* [[BITCAST]], i8** [[G_PRIV_REF]],
147 // BLOCKS: call i32 @__kmpc_reduce(
148 // BLOCKS: switch i32 %{{.+}}, label %[[REDUCTION_DONE:.+]] [
149 // BLOCKS: i32 1, label %[[CASE1:.+]]
150 // BLOCKS: i32 2, label %[[CASE2:.+]]
151 // BLOCKS: [[CASE1]]
152 // BLOCKS: [[G_VAL:%.+]] = load double, double* [[G]]
153 // BLOCKS: [[G_PRIV_VAL:%.+]] = load double, double* [[G_PRIVATE_ADDR]]
154 // BLOCKS: [[ADD:%.+]] = fadd double [[G_VAL]], [[G_PRIV_VAL]]
155 // BLOCKS: store double [[ADD]], double* [[G]]
156 // BLOCKS: call void @__kmpc_end_reduce(
157 // BLOCKS: br label %[[REDUCTION_DONE]]
158 // BLOCKS: [[CASE2]]
159 // BLOCKS: [[G_PRIV_VAL:%.+]] = load double, double* [[G_PRIVATE_ADDR]]
160 // BLOCKS: fadd double
161 // BLOCKS: cmpxchg i64*
Alexey Bataev69a47792015-05-07 03:54:03 +0000162 // BLOCKS: call void @__kmpc_end_reduce(
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000163 // BLOCKS: br label %[[REDUCTION_DONE]]
164 // BLOCKS: [[REDUCTION_DONE]]
165 // BLOCKS: ret void
166 ^{
167 // BLOCKS: define {{.+}} void {{@.+}}(i8*
168 g = 2;
Alexey Bataevcaacd532015-09-04 11:26:21 +0000169 g1 = 2;
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000170 // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
Alexey Bataevb44fdfc2015-07-14 10:32:29 +0000171 // BLOCKS: store double 2.0{{.+}}, double*
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000172 // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
173 // BLOCKS: ret
174 }();
175 }
176 }();
177 return 0;
178#else
179 S<float> test;
180 float t_var = 0, t_var1;
181 int vec[] = {1, 2};
182 S<float> s_arr[] = {1, 2};
Alexey Bataevcaacd532015-09-04 11:26:21 +0000183 S<float> &var = test;
184 S<float> var1;
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000185#pragma omp parallel
186#pragma omp for reduction(+:t_var) reduction(&:var) reduction(&& : var1) reduction(min: t_var1)
187 for (int i = 0; i < 2; ++i) {
188 vec[i] = t_var;
189 s_arr[i] = var;
190 }
191 return tmain<int>();
192#endif
193}
194
195// CHECK: define {{.*}}i{{[0-9]+}} @main()
196// CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]],
197// CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
Alexey Bataev2377fe92015-09-10 08:12:02 +0000198// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 6, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, float*, [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]*, float*, [2 x i32]*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK:@.+]] to void
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000199// CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]()
200// CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]*
201// CHECK: ret
202//
Alexey Bataev2377fe92015-09-10 08:12:02 +0000203// CHECK: define internal void [[MAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, float* dereferenceable(4) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}}, float* dereferenceable(4) %{{.+}}, [2 x i32]* dereferenceable(8) %vec, [2 x [[S_FLOAT_TY]]]* dereferenceable(8) %{{.+}})
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000204// CHECK: [[T_VAR_PRIV:%.+]] = alloca float,
205// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
206// CHECK: [[VAR1_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
207// CHECK: [[T_VAR1_PRIV:%.+]] = alloca float,
208
209// Reduction list for runtime.
210// CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*],
211
212// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
213
Alexey Bataev2377fe92015-09-10 08:12:02 +0000214// CHECK: [[T_VAR_REF:%.+]] = load float*, float** %
215// CHECK: [[VAR1_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %
216// CHECK: [[T_VAR1_REF:%.+]] = load float*, float** %
217
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000218// For + reduction operation initial value of private variable is 0.
219// CHECK: store float 0.0{{.+}}, float* [[T_VAR_PRIV]],
220
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000221// For & reduction operation initial value of private variable is ones in all bits.
Alexey Bataev2377fe92015-09-10 08:12:02 +0000222// CHECK: [[VAR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000223// CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
224
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000225// For && reduction operation initial value of private variable is 1.0.
226// CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[VAR1_PRIV]])
227
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000228// For min reduction operation initial value of private variable is largest repesentable value.
229// CHECK: store float 0x47EFFFFFE0000000, float* [[T_VAR1_PRIV]],
230
231
232// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
233// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
234// CHECK: call void @__kmpc_for_static_init_4(
235// Skip checks for internal operations.
236// CHECK: call void @__kmpc_for_static_fini(
237
238// void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
239
John McCall7f416cc2015-09-08 08:05:57 +0000240// CHECK: [[T_VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000241// CHECK: [[BITCAST:%.+]] = bitcast float* [[T_VAR_PRIV]] to i8*
242// CHECK: store i8* [[BITCAST]], i8** [[T_VAR_PRIV_REF]],
John McCall7f416cc2015-09-08 08:05:57 +0000243// CHECK: [[VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 1
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000244// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_PRIV]] to i8*
245// CHECK: store i8* [[BITCAST]], i8** [[VAR_PRIV_REF]],
John McCall7f416cc2015-09-08 08:05:57 +0000246// CHECK: [[VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 2
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000247// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR1_PRIV]] to i8*
248// CHECK: store i8* [[BITCAST]], i8** [[VAR1_PRIV_REF]],
John McCall7f416cc2015-09-08 08:05:57 +0000249// CHECK: [[T_VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 3
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000250// CHECK: [[BITCAST:%.+]] = bitcast float* [[T_VAR1_PRIV]] to i8*
251// CHECK: store i8* [[BITCAST]], i8** [[T_VAR1_PRIV_REF]],
252
253// res = __kmpc_reduce(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>);
254
255// CHECK: [[BITCAST:%.+]] = bitcast [4 x i8*]* [[RED_LIST]] to i8*
256// 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]])
257
258// switch(res)
259// CHECK: switch i32 [[RES]], label %[[RED_DONE:.+]] [
260// CHECK: i32 1, label %[[CASE1:.+]]
261// CHECK: i32 2, label %[[CASE2:.+]]
262// CHECK: ]
263
264// case 1:
265// t_var += t_var_reduction;
266// CHECK: [[T_VAR_VAL:%.+]] = load float, float* [[T_VAR_REF]],
267// CHECK: [[T_VAR_PRIV_VAL:%.+]] = load float, float* [[T_VAR_PRIV]],
268// CHECK: [[UP:%.+]] = fadd float [[T_VAR_VAL]], [[T_VAR_PRIV_VAL]]
269// CHECK: store float [[UP]], float* [[T_VAR_REF]],
270
271// var = var.operator &(var_reduction);
272// CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_FLOAT_TY]]* @{{.+}}([[S_FLOAT_TY]]* [[VAR_REF]], [[S_FLOAT_TY]]* dereferenceable(4) [[VAR_PRIV]])
273// CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_REF]] to i8*
274// CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[UP]] to i8*
275// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
276
277// var1 = var1.operator &&(var1_reduction);
278// CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_REF]])
279// CHECK: [[VAR1_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0
Alexey Bataev69a47792015-05-07 03:54:03 +0000280// CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[END2:.+]]
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000281// CHECK: [[TRUE]]
282// CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_PRIV]])
283// CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000284// CHECK: br label %[[END2]]
285// CHECK: [[END2]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000286// CHECK: [[COND_LVALUE:%.+]] = phi i1 [ false, %{{.+}} ], [ [[VAR1_REDUCTION_BOOL]], %[[TRUE]] ]
287// CHECK: [[CONV:%.+]] = uitofp i1 [[COND_LVALUE]] to float
288// CHECK: call void @{{.+}}([[S_FLOAT_TY]]* [[COND_LVALUE:%.+]], float [[CONV]])
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000289// CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR1_REF]] to i8*
290// CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[COND_LVALUE]] to i8*
291// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
292
293// t_var1 = min(t_var1, t_var1_reduction);
294// CHECK: [[T_VAR1_VAL:%.+]] = load float, float* [[T_VAR1_REF]],
295// CHECK: [[T_VAR1_PRIV_VAL:%.+]] = load float, float* [[T_VAR1_PRIV]],
296// CHECK: [[CMP:%.+]] = fcmp olt float [[T_VAR1_VAL]], [[T_VAR1_PRIV_VAL]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000297// CHECK: br i1 [[CMP]]
298// CHECK: [[UP:%.+]] = phi float
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000299// CHECK: store float [[UP]], float* [[T_VAR1_REF]],
300
301// __kmpc_end_reduce(<loc>, <gtid>, &<lock>);
302// CHECK: call void @__kmpc_end_reduce(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]])
303
304// break;
305// CHECK: br label %[[RED_DONE]]
306
307// case 2:
308// t_var += t_var_reduction;
309// CHECK: load float, float* [[T_VAR_PRIV]]
310// CHECK: [[T_VAR_REF_INT:%.+]] = bitcast float* [[T_VAR_REF]] to i32*
Alexey Bataevf0ab5532015-05-15 08:36:34 +0000311// CHECK: [[OLD1:%.+]] = load atomic i32, i32* [[T_VAR_REF_INT]] monotonic,
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000312// CHECK: br label %[[CONT:.+]]
313// CHECK: [[CONT]]
Alexey Bataevf0ab5532015-05-15 08:36:34 +0000314// CHECK: [[ORIG_OLD_INT:%.+]] = phi i32 [ [[OLD1]], %{{.+}} ], [ [[OLD2:%.+]], %[[CONT]] ]
315// CHECK: fadd float
316// CHECK: [[UP_INT:%.+]] = load i32, i32*
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000317// CHECK: [[T_VAR_REF_INT:%.+]] = bitcast float* [[T_VAR_REF]] to i32*
318// CHECK: [[RES:%.+]] = cmpxchg i32* [[T_VAR_REF_INT]], i32 [[ORIG_OLD_INT]], i32 [[UP_INT]] monotonic monotonic
Alexey Bataevf0ab5532015-05-15 08:36:34 +0000319// CHECK: [[OLD2:%.+]] = extractvalue { i32, i1 } [[RES]], 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000320// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i32, i1 } [[RES]], 1
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000321// CHECK: br i1 [[SUCCESS_FAIL]], label %[[ATOMIC_DONE:.+]], label %[[CONT]]
322// CHECK: [[ATOMIC_DONE]]
323
324// var = var.operator &(var_reduction);
325// CHECK: call void @__kmpc_critical(
326// CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_FLOAT_TY]]* @{{.+}}([[S_FLOAT_TY]]* [[VAR_REF]], [[S_FLOAT_TY]]* dereferenceable(4) [[VAR_PRIV]])
327// CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_REF]] to i8*
328// CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[UP]] to i8*
329// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
330// CHECK: call void @__kmpc_end_critical(
331
332// var1 = var1.operator &&(var1_reduction);
333// CHECK: call void @__kmpc_critical(
334// CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_REF]])
335// CHECK: [[VAR1_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0
Alexey Bataev69a47792015-05-07 03:54:03 +0000336// CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[END2:.+]]
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000337// CHECK: [[TRUE]]
338// CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_PRIV]])
339// CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000340// CHECK: br label %[[END2]]
341// CHECK: [[END2]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000342// CHECK: [[COND_LVALUE:%.+]] = phi i1 [ false, %{{.+}} ], [ [[VAR1_REDUCTION_BOOL]], %[[TRUE]] ]
343// CHECK: [[CONV:%.+]] = uitofp i1 [[COND_LVALUE]] to float
344// CHECK: call void @{{.+}}([[S_FLOAT_TY]]* [[COND_LVALUE:%.+]], float [[CONV]])
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000345// CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR1_REF]] to i8*
346// CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[COND_LVALUE]] to i8*
347// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
348// CHECK: call void @__kmpc_end_critical(
349
350// t_var1 = min(t_var1, t_var1_reduction);
351// CHECK: load float, float* [[T_VAR1_PRIV]]
352// CHECK: [[T_VAR1_REF_INT:%.+]] = bitcast float* [[T_VAR1_REF]] to i32*
Alexey Bataevf0ab5532015-05-15 08:36:34 +0000353// CHECK: [[OLD1:%.+]] = load atomic i32, i32* [[T_VAR1_REF_INT]] monotonic,
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000354// CHECK: br label %[[CONT:.+]]
355// CHECK: [[CONT]]
Alexey Bataevf0ab5532015-05-15 08:36:34 +0000356// CHECK: [[ORIG_OLD_INT:%.+]] = phi i32 [ [[OLD1]], %{{.+}} ], [ [[OLD2:%.+]], %{{.+}} ]
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000357// CHECK: [[CMP:%.+]] = fcmp olt float
Alexey Bataev69a47792015-05-07 03:54:03 +0000358// CHECK: br i1 [[CMP]]
Alexey Bataevf0ab5532015-05-15 08:36:34 +0000359// CHECK: phi float
360// CHECK: [[UP_INT:%.+]] = load i32
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000361// CHECK: [[T_VAR1_REF_INT:%.+]] = bitcast float* [[T_VAR1_REF]] to i32*
362// CHECK: [[RES:%.+]] = cmpxchg i32* [[T_VAR1_REF_INT]], i32 [[ORIG_OLD_INT]], i32 [[UP_INT]] monotonic monotonic
Alexey Bataevf0ab5532015-05-15 08:36:34 +0000363// CHECK: [[OLD2:%.+]] = extractvalue { i32, i1 } [[RES]], 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000364// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i32, i1 } [[RES]], 1
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000365// CHECK: br i1 [[SUCCESS_FAIL]], label %[[ATOMIC_DONE:.+]], label %[[CONT]]
366// CHECK: [[ATOMIC_DONE]]
367
Alexey Bataev69a47792015-05-07 03:54:03 +0000368// __kmpc_end_reduce(<loc>, <gtid>, &<lock>);
369// CHECK: call void @__kmpc_end_reduce(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]])
370
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000371// break;
372// CHECK: br label %[[RED_DONE]]
373// CHECK: [[RED_DONE]]
374// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
375// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]*
376// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
377// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
378
379// CHECK: ret void
380
381// void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
382// *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]);
383// ...
384// *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1],
385// *(Type<n>-1*)rhs[<n>-1]);
386// }
387// CHECK: define internal void [[REDUCTION_FUNC]](i8*, i8*)
388// t_var_lhs = (float*)lhs[0];
John McCall7f416cc2015-09-08 08:05:57 +0000389// CHECK: [[T_VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS:%.+]], i64 0, i64 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000390// CHECK: [[T_VAR_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR_RHS_REF]],
391// CHECK: [[T_VAR_RHS:%.+]] = bitcast i8* [[T_VAR_RHS_VOID]] to float*
392// t_var_rhs = (float*)rhs[0];
John McCall7f416cc2015-09-08 08:05:57 +0000393// CHECK: [[T_VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS:%.+]], i64 0, i64 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000394// CHECK: [[T_VAR_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR_LHS_REF]],
395// CHECK: [[T_VAR_LHS:%.+]] = bitcast i8* [[T_VAR_LHS_VOID]] to float*
396
397// var_lhs = (S<float>*)lhs[1];
John McCall7f416cc2015-09-08 08:05:57 +0000398// CHECK: [[VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 1
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000399// CHECK: [[VAR_RHS_VOID:%.+]] = load i8*, i8** [[VAR_RHS_REF]],
400// CHECK: [[VAR_RHS:%.+]] = bitcast i8* [[VAR_RHS_VOID]] to [[S_FLOAT_TY]]*
401// var_rhs = (S<float>*)rhs[1];
John McCall7f416cc2015-09-08 08:05:57 +0000402// CHECK: [[VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 1
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000403// CHECK: [[VAR_LHS_VOID:%.+]] = load i8*, i8** [[VAR_LHS_REF]],
404// CHECK: [[VAR_LHS:%.+]] = bitcast i8* [[VAR_LHS_VOID]] to [[S_FLOAT_TY]]*
405
406// var1_lhs = (S<float>*)lhs[2];
John McCall7f416cc2015-09-08 08:05:57 +0000407// CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 2
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000408// CHECK: [[VAR1_RHS_VOID:%.+]] = load i8*, i8** [[VAR1_RHS_REF]],
409// CHECK: [[VAR1_RHS:%.+]] = bitcast i8* [[VAR1_RHS_VOID]] to [[S_FLOAT_TY]]*
410// var1_rhs = (S<float>*)rhs[2];
John McCall7f416cc2015-09-08 08:05:57 +0000411// CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 2
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000412// CHECK: [[VAR1_LHS_VOID:%.+]] = load i8*, i8** [[VAR1_LHS_REF]],
413// CHECK: [[VAR1_LHS:%.+]] = bitcast i8* [[VAR1_LHS_VOID]] to [[S_FLOAT_TY]]*
414
415// t_var1_lhs = (float*)lhs[3];
John McCall7f416cc2015-09-08 08:05:57 +0000416// CHECK: [[T_VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 3
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000417// CHECK: [[T_VAR1_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_RHS_REF]],
418// CHECK: [[T_VAR1_RHS:%.+]] = bitcast i8* [[T_VAR1_RHS_VOID]] to float*
419// t_var1_rhs = (float*)rhs[3];
John McCall7f416cc2015-09-08 08:05:57 +0000420// CHECK: [[T_VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 3
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000421// CHECK: [[T_VAR1_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_LHS_REF]],
422// CHECK: [[T_VAR1_LHS:%.+]] = bitcast i8* [[T_VAR1_LHS_VOID]] to float*
423
424// t_var_lhs += t_var_rhs;
425// CHECK: [[T_VAR_LHS_VAL:%.+]] = load float, float* [[T_VAR_LHS]],
426// CHECK: [[T_VAR_RHS_VAL:%.+]] = load float, float* [[T_VAR_RHS]],
427// CHECK: [[UP:%.+]] = fadd float [[T_VAR_LHS_VAL]], [[T_VAR_RHS_VAL]]
428// CHECK: store float [[UP]], float* [[T_VAR_LHS]],
429
430// var_lhs = var_lhs.operator &(var_rhs);
431// CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_FLOAT_TY]]* @{{.+}}([[S_FLOAT_TY]]* [[VAR_LHS]], [[S_FLOAT_TY]]* dereferenceable(4) [[VAR_RHS]])
432// CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR_LHS]] to i8*
433// CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[UP]] to i8*
434// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
435
436// var1_lhs = var1_lhs.operator &&(var1_rhs);
437// CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_LHS]])
438// CHECK: [[VAR1_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0
Alexey Bataev69a47792015-05-07 03:54:03 +0000439// CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[END2:.+]]
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000440// CHECK: [[TRUE]]
441// CHECK: [[TO_FLOAT:%.+]] = call float @{{.+}}([[S_FLOAT_TY]]* [[VAR1_RHS]])
442// CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = fcmp une float [[TO_FLOAT]], 0.0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000443// CHECK: br label %[[END2]]
444// CHECK: [[END2]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000445// CHECK: [[COND_LVALUE:%.+]] = phi i1 [ false, %{{.+}} ], [ [[VAR1_REDUCTION_BOOL]], %[[TRUE]] ]
446// CHECK: [[CONV:%.+]] = uitofp i1 [[COND_LVALUE]] to float
447// CHECK: call void @{{.+}}([[S_FLOAT_TY]]* [[COND_LVALUE:%.+]], float [[CONV]])
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000448// CHECK: [[BC1:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR1_LHS]] to i8*
449// CHECK: [[BC2:%.+]] = bitcast [[S_FLOAT_TY]]* [[COND_LVALUE]] to i8*
450// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
451
452// t_var1_lhs = min(t_var1_lhs, t_var1_rhs);
453// CHECK: [[T_VAR1_LHS_VAL:%.+]] = load float, float* [[T_VAR1_LHS]],
454// CHECK: [[T_VAR1_RHS_VAL:%.+]] = load float, float* [[T_VAR1_RHS]],
455// CHECK: [[CMP:%.+]] = fcmp olt float [[T_VAR1_LHS_VAL]], [[T_VAR1_RHS_VAL]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000456// CHECK: br i1 [[CMP]]
457// CHECK: [[UP:%.+]] = phi float
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000458// CHECK: store float [[UP]], float* [[T_VAR1_LHS]],
459// CHECK: ret void
460
461// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
462// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
463// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
Alexey Bataev2377fe92015-09-10 08:12:02 +0000464// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 6, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i32*, [[S_INT_TY]]*, [[S_INT_TY]]*, i32*, [2 x i32]*, [2 x [[S_INT_TY]]]*)* [[TMAIN_MICROTASK:@.+]] to void
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000465// CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]*
466// CHECK: ret
467//
Alexey Bataev2377fe92015-09-10 08:12:02 +0000468// CHECK: define internal void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, [[S_INT_TY]]* dereferenceable(4) %{{.+}}, [[S_INT_TY]]* dereferenceable(4) %{{.+}}, i32* dereferenceable(4) %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(8) %{{.+}})
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000469// 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: alloca i{{[0-9]+}},
474// CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}},
475// CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]],
476// CHECK: [[VAR1_PRIV:%.+]] = alloca [[S_INT_TY]],
477// CHECK: [[T_VAR1_PRIV:%.+]] = alloca i{{[0-9]+}},
478
479// Reduction list for runtime.
480// CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*],
481
482// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
483
Alexey Bataev2377fe92015-09-10 08:12:02 +0000484// CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %
485// CHECK: [[VAR1_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** %
486// CHECK: [[T_VAR1_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %
487
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000488// For + reduction operation initial value of private variable is 0.
489// CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* [[T_VAR_PRIV]],
490
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000491// For & reduction operation initial value of private variable is ones in all bits.
Alexey Bataev2377fe92015-09-10 08:12:02 +0000492// CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** %
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000493// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[VAR_PRIV]])
494
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000495// For && reduction operation initial value of private variable is 1.0.
496// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[VAR1_PRIV]])
497
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000498// For min reduction operation initial value of private variable is largest repesentable value.
499// CHECK: store i{{[0-9]+}} 2147483647, i{{[0-9]+}}* [[T_VAR1_PRIV]],
500
501// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
502// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
503// CHECK: call void @__kmpc_for_static_init_4(
504// Skip checks for internal operations.
505// CHECK: call void @__kmpc_for_static_fini(
506
507// void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
508
John McCall7f416cc2015-09-08 08:05:57 +0000509// CHECK: [[T_VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000510// CHECK: [[BITCAST:%.+]] = bitcast i{{[0-9]+}}* [[T_VAR_PRIV]] to i8*
511// CHECK: store i8* [[BITCAST]], i8** [[T_VAR_PRIV_REF]],
John McCall7f416cc2015-09-08 08:05:57 +0000512// CHECK: [[VAR_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 1
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000513// CHECK: [[BITCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR_PRIV]] to i8*
514// CHECK: store i8* [[BITCAST]], i8** [[VAR_PRIV_REF]],
John McCall7f416cc2015-09-08 08:05:57 +0000515// CHECK: [[VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 2
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000516// CHECK: [[BITCAST:%.+]] = bitcast [[S_INT_TY]]* [[VAR1_PRIV]] to i8*
517// CHECK: store i8* [[BITCAST]], i8** [[VAR1_PRIV_REF]],
John McCall7f416cc2015-09-08 08:05:57 +0000518// CHECK: [[T_VAR1_PRIV_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST]], i64 0, i64 3
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000519// CHECK: [[BITCAST:%.+]] = bitcast i{{[0-9]+}}* [[T_VAR1_PRIV]] to i8*
520// CHECK: store i8* [[BITCAST]], i8** [[T_VAR1_PRIV_REF]],
521
522// res = __kmpc_reduce_nowait(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>);
523
524// CHECK: [[BITCAST:%.+]] = bitcast [4 x i8*]* [[RED_LIST]] to i8*
525// 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]])
526
527// switch(res)
528// CHECK: switch i32 [[RES]], label %[[RED_DONE:.+]] [
529// CHECK: i32 1, label %[[CASE1:.+]]
530// CHECK: i32 2, label %[[CASE2:.+]]
531// CHECK: ]
532
533// case 1:
534// t_var += t_var_reduction;
535// CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]],
536// CHECK: [[T_VAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]],
537// CHECK: [[UP:%.+]] = add nsw i{{[0-9]+}} [[T_VAR_VAL]], [[T_VAR_PRIV_VAL]]
538// CHECK: store i{{[0-9]+}} [[UP]], i{{[0-9]+}}* [[T_VAR_REF]],
539
540// var = var.operator &(var_reduction);
541// CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_INT_TY]]* @{{.+}}([[S_INT_TY]]* [[VAR_REF]], [[S_INT_TY]]* dereferenceable(4) [[VAR_PRIV]])
542// CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR_REF]] to i8*
543// CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[UP]] to i8*
544// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
545
546// var1 = var1.operator &&(var1_reduction);
547// CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_REF]])
548// CHECK: [[VAR1_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0
Alexey Bataev69a47792015-05-07 03:54:03 +0000549// CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[END2:.+]]
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000550// CHECK: [[TRUE]]
551// CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_PRIV]])
552// CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000553// CHECK: br label %[[END2]]
554// CHECK: [[END2]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000555// CHECK: [[COND_LVALUE:%.+]] = phi i1 [ false, %{{.+}} ], [ [[VAR1_REDUCTION_BOOL]], %[[TRUE]] ]
556// CHECK: [[CONV:%.+]] = zext i1 [[COND_LVALUE]] to i32
557// CHECK: call void @{{.+}}([[S_INT_TY]]* [[COND_LVALUE:%.+]], i32 [[CONV]])
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000558// CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR1_REF]] to i8*
559// CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[COND_LVALUE]] to i8*
560// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
561
562// t_var1 = min(t_var1, t_var1_reduction);
563// CHECK: [[T_VAR1_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_REF]],
564// CHECK: [[T_VAR1_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_PRIV]],
565// CHECK: [[CMP:%.+]] = icmp slt i{{[0-9]+}} [[T_VAR1_VAL]], [[T_VAR1_PRIV_VAL]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000566// CHECK: br i1 [[CMP]]
567// CHECK: [[UP:%.+]] = phi i32
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000568// CHECK: store i{{[0-9]+}} [[UP]], i{{[0-9]+}}* [[T_VAR1_REF]],
569
570// __kmpc_end_reduce_nowait(<loc>, <gtid>, &<lock>);
571// CHECK: call void @__kmpc_end_reduce_nowait(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]])
572
573// break;
574// CHECK: br label %[[RED_DONE]]
575
576// case 2:
577// t_var += t_var_reduction;
578// CHECK: [[T_VAR_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_PRIV]]
579// CHECK: atomicrmw add i32* [[T_VAR_REF]], i32 [[T_VAR_PRIV_VAL]] monotonic
580
581// var = var.operator &(var_reduction);
582// CHECK: call void @__kmpc_critical(
583// CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_INT_TY]]* @{{.+}}([[S_INT_TY]]* [[VAR_REF]], [[S_INT_TY]]* dereferenceable(4) [[VAR_PRIV]])
584// CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR_REF]] to i8*
585// CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[UP]] to i8*
586// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
587// CHECK: call void @__kmpc_end_critical(
588
589// var1 = var1.operator &&(var1_reduction);
590// CHECK: call void @__kmpc_critical(
591// CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_REF]])
592// CHECK: [[VAR1_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0
Alexey Bataev69a47792015-05-07 03:54:03 +0000593// CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[END2:.+]]
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000594// CHECK: [[TRUE]]
595// CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_PRIV]])
596// CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000597// CHECK: br label %[[END2]]
598// CHECK: [[END2]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000599// CHECK: [[COND_LVALUE:%.+]] = phi i1 [ false, %{{.+}} ], [ [[VAR1_REDUCTION_BOOL]], %[[TRUE]] ]
600// CHECK: [[CONV:%.+]] = zext i1 [[COND_LVALUE]] to i32
601// CHECK: call void @{{.+}}([[S_INT_TY]]* [[COND_LVALUE:%.+]], i32 [[CONV]])
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000602// CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR1_REF]] to i8*
603// CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[COND_LVALUE]] to i8*
604// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
605// CHECK: call void @__kmpc_end_critical(
606
607// t_var1 = min(t_var1, t_var1_reduction);
608// CHECK: [[T_VAR1_PRIV_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_PRIV]]
609// CHECK: atomicrmw min i32* [[T_VAR1_REF]], i32 [[T_VAR1_PRIV_VAL]] monotonic
610
611// break;
612// CHECK: br label %[[RED_DONE]]
613// CHECK: [[RED_DONE]]
614// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]])
615// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]*
616// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
617// CHECK: ret void
618
619// void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
620// *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]);
621// ...
622// *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1],
623// *(Type<n>-1*)rhs[<n>-1]);
624// }
625// CHECK: define internal void [[REDUCTION_FUNC]](i8*, i8*)
626// t_var_lhs = (i{{[0-9]+}}*)lhs[0];
John McCall7f416cc2015-09-08 08:05:57 +0000627// CHECK: [[T_VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS:%.+]], i64 0, i64 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000628// CHECK: [[T_VAR_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR_RHS_REF]],
629// CHECK: [[T_VAR_RHS:%.+]] = bitcast i8* [[T_VAR_RHS_VOID]] to i{{[0-9]+}}*
630// t_var_rhs = (i{{[0-9]+}}*)rhs[0];
John McCall7f416cc2015-09-08 08:05:57 +0000631// CHECK: [[T_VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS:%.+]], i64 0, i64 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000632// CHECK: [[T_VAR_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR_LHS_REF]],
633// CHECK: [[T_VAR_LHS:%.+]] = bitcast i8* [[T_VAR_LHS_VOID]] to i{{[0-9]+}}*
634
635// var_lhs = (S<i{{[0-9]+}}>*)lhs[1];
John McCall7f416cc2015-09-08 08:05:57 +0000636// CHECK: [[VAR_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 1
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000637// CHECK: [[VAR_RHS_VOID:%.+]] = load i8*, i8** [[VAR_RHS_REF]],
638// CHECK: [[VAR_RHS:%.+]] = bitcast i8* [[VAR_RHS_VOID]] to [[S_INT_TY]]*
639// var_rhs = (S<i{{[0-9]+}}>*)rhs[1];
John McCall7f416cc2015-09-08 08:05:57 +0000640// CHECK: [[VAR_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 1
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000641// CHECK: [[VAR_LHS_VOID:%.+]] = load i8*, i8** [[VAR_LHS_REF]],
642// CHECK: [[VAR_LHS:%.+]] = bitcast i8* [[VAR_LHS_VOID]] to [[S_INT_TY]]*
643
644// var1_lhs = (S<i{{[0-9]+}}>*)lhs[2];
John McCall7f416cc2015-09-08 08:05:57 +0000645// CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 2
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000646// CHECK: [[VAR1_RHS_VOID:%.+]] = load i8*, i8** [[VAR1_RHS_REF]],
647// CHECK: [[VAR1_RHS:%.+]] = bitcast i8* [[VAR1_RHS_VOID]] to [[S_INT_TY]]*
648// var1_rhs = (S<i{{[0-9]+}}>*)rhs[2];
John McCall7f416cc2015-09-08 08:05:57 +0000649// CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 2
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000650// CHECK: [[VAR1_LHS_VOID:%.+]] = load i8*, i8** [[VAR1_LHS_REF]],
651// CHECK: [[VAR1_LHS:%.+]] = bitcast i8* [[VAR1_LHS_VOID]] to [[S_INT_TY]]*
652
653// t_var1_lhs = (i{{[0-9]+}}*)lhs[3];
John McCall7f416cc2015-09-08 08:05:57 +0000654// CHECK: [[T_VAR1_RHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_RHS]], i64 0, i64 3
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000655// CHECK: [[T_VAR1_RHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_RHS_REF]],
656// CHECK: [[T_VAR1_RHS:%.+]] = bitcast i8* [[T_VAR1_RHS_VOID]] to i{{[0-9]+}}*
657// t_var1_rhs = (i{{[0-9]+}}*)rhs[3];
John McCall7f416cc2015-09-08 08:05:57 +0000658// CHECK: [[T_VAR1_LHS_REF:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[RED_LIST_LHS]], i64 0, i64 3
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000659// CHECK: [[T_VAR1_LHS_VOID:%.+]] = load i8*, i8** [[T_VAR1_LHS_REF]],
660// CHECK: [[T_VAR1_LHS:%.+]] = bitcast i8* [[T_VAR1_LHS_VOID]] to i{{[0-9]+}}*
661
662// t_var_lhs += t_var_rhs;
663// CHECK: [[T_VAR_LHS_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_LHS]],
664// CHECK: [[T_VAR_RHS_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_RHS]],
665// CHECK: [[UP:%.+]] = add nsw i{{[0-9]+}} [[T_VAR_LHS_VAL]], [[T_VAR_RHS_VAL]]
666// CHECK: store i{{[0-9]+}} [[UP]], i{{[0-9]+}}* [[T_VAR_LHS]],
667
668// var_lhs = var_lhs.operator &(var_rhs);
669// CHECK: [[UP:%.+]] = call dereferenceable(4) [[S_INT_TY]]* @{{.+}}([[S_INT_TY]]* [[VAR_LHS]], [[S_INT_TY]]* dereferenceable(4) [[VAR_RHS]])
670// CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR_LHS]] to i8*
671// CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[UP]] to i8*
672// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
673
674// var1_lhs = var1_lhs.operator &&(var1_rhs);
675// CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_LHS]])
676// CHECK: [[VAR1_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0
Alexey Bataev69a47792015-05-07 03:54:03 +0000677// CHECK: br i1 [[VAR1_BOOL]], label %[[TRUE:.+]], label %[[END2:.+]]
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000678// CHECK: [[TRUE]]
679// CHECK: [[TO_INT:%.+]] = call i{{[0-9]+}} @{{.+}}([[S_INT_TY]]* [[VAR1_RHS]])
680// CHECK: [[VAR1_REDUCTION_BOOL:%.+]] = icmp ne i{{[0-9]+}} [[TO_INT]], 0
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000681// CHECK: br label %[[END2]]
682// CHECK: [[END2]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000683// CHECK: [[COND_LVALUE:%.+]] = phi i1 [ false, %{{.+}} ], [ [[VAR1_REDUCTION_BOOL]], %[[TRUE]] ]
684// CHECK: [[CONV:%.+]] = zext i1 [[COND_LVALUE]] to i32
685// CHECK: call void @{{.+}}([[S_INT_TY]]* [[COND_LVALUE:%.+]], i32 [[CONV]])
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000686// CHECK: [[BC1:%.+]] = bitcast [[S_INT_TY]]* [[VAR1_LHS]] to i8*
687// CHECK: [[BC2:%.+]] = bitcast [[S_INT_TY]]* [[COND_LVALUE]] to i8*
688// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC1]], i8* [[BC2]], i64 4, i32 4, i1 false)
689
690// t_var1_lhs = min(t_var1_lhs, t_var1_rhs);
691// CHECK: [[T_VAR1_LHS_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_LHS]],
692// CHECK: [[T_VAR1_RHS_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR1_RHS]],
693// CHECK: [[CMP:%.+]] = icmp slt i{{[0-9]+}} [[T_VAR1_LHS_VAL]], [[T_VAR1_RHS_VAL]]
Alexey Bataev69a47792015-05-07 03:54:03 +0000694// CHECK: br i1 [[CMP]]
695// CHECK: [[UP:%.+]] = phi i32
Alexey Bataev7ebe5fd2015-04-22 13:43:03 +0000696// CHECK: store i{{[0-9]+}} [[UP]], i{{[0-9]+}}* [[T_VAR1_LHS]],
697// CHECK: ret void
698
699#endif
700