]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/OpenMP/declare_reduction_codegen.cpp
Vendor import of clang trunk r338150:
[FreeBSD/FreeBSD.git] / test / OpenMP / declare_reduction_codegen.cpp
1 // RUN: %clang_cc1 -verify -fopenmp -x c++ -emit-llvm %s -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -o - -femit-all-decls -disable-llvm-passes | FileCheck %s
2 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -emit-pch -o %t %s -femit-all-decls -disable-llvm-passes
3 // RUN: %clang_cc1 -fopenmp -x c++ -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefix=CHECK-LOAD %s
4
5 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -emit-llvm %s -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefix SIMD-ONLY0 %s
6 // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -emit-pch -o %t %s -femit-all-decls -disable-llvm-passes
7 // RUN: %clang_cc1 -fopenmp-simd -x c++ -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefix SIMD-ONLY0 %s
8 // SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
9 // expected-no-diagnostics
10
11 #ifndef HEADER
12 #define HEADER
13
14 // CHECK: [[SSS_INT:.+]] = type { i32 }
15 // CHECK-LOAD: [[SSS_INT:.+]] = type { i32 }
16
17 // CHECK: add
18 void add(short &out, short &in) {}
19
20 #pragma omp declare reduction(my_add : short : add(omp_out, omp_in))
21
22 // CHECK: define internal void @.
23 // CHECK: call void @{{.+}}add{{.+}}(
24 // CHECK: ret void
25
26 // CHECK: foo_reduction_array
27 void foo_reduction_array() {
28   short y[1];
29   // CHECK: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
30 #pragma omp parallel for reduction(my_add : y)
31   for (int i = 0; i < 1; i++) {
32   }
33 }
34
35 // CHECK: define internal void @
36
37 #pragma omp declare reduction(+ : int, char : omp_out *= omp_in)
38 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
39 // CHECK: [[MUL:%.+]] = mul nsw i32
40 // CHECK-NEXT: store i32 [[MUL]], i32*
41 // CHECK-NEXT: ret void
42 // CHECK-NEXT: }
43 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
44 // CHECK-LOAD: [[MUL:%.+]] = mul nsw i32
45 // CHECK-LOAD-NEXT: store i32 [[MUL]], i32*
46 // CHECK-LOAD-NEXT: ret void
47 // CHECK-LOAD-NEXT: }
48
49 // CHECK: define internal {{.*}}void @{{[^(]+}}(i8* noalias, i8* noalias)
50 // CHECK: sext i8
51 // CHECK: sext i8
52 // CHECK: [[MUL:%.+]] = mul nsw i32
53 // CHECK-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i8
54 // CHECK-NEXT: store i8 [[TRUNC]], i8*
55 // CHECK-NEXT: ret void
56 // CHECK-NEXT: }
57
58 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i8* noalias, i8* noalias)
59 // CHECK-LOAD: sext i8
60 // CHECK-LOAD: sext i8
61 // CHECK-LOAD: [[MUL:%.+]] = mul nsw i32
62 // CHECK-LOAD-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i8
63 // CHECK-LOAD-NEXT: store i8 [[TRUNC]], i8*
64 // CHECK-LOAD-NEXT: ret void
65 // CHECK-LOAD-NEXT: }
66
67 template <class T>
68 struct SSS {
69   T a;
70   SSS() : a() {}
71 #pragma omp declare reduction(fun : T : omp_out ^= omp_in) initializer(omp_priv = 24 + omp_orig)
72 };
73
74 SSS<int> d;
75
76 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
77 // CHECK: [[XOR:%.+]] = xor i32
78 // CHECK-NEXT: store i32 [[XOR]], i32*
79 // CHECK-NEXT: ret void
80 // CHECK-NEXT: }
81
82 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
83 // CHECK: [[ADD:%.+]] = add nsw i32 24,
84 // CHECK-NEXT: store i32 [[ADD]], i32*
85 // CHECK-NEXT: ret void
86 // CHECK-NEXT: }
87
88 // CHECK: define {{.*}}void [[INIT:@[^(]+]]([[SSS_INT]]*
89 // CHECK-LOAD: define {{.*}}void [[INIT:@[^(]+]]([[SSS_INT]]*
90 void init(SSS<int> &lhs, SSS<int> &rhs) {}
91
92 #pragma omp declare reduction(fun : SSS < int > : omp_out = omp_in) initializer(init(omp_priv, omp_orig))
93 // CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias)
94 // CHECK: call void @llvm.memcpy
95 // CHECK-NEXT: ret void
96 // CHECK-NEXT: }
97 // CHECK: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias)
98 // CHECK: call {{.*}}void [[INIT]](
99 // CHECK-NEXT: ret void
100 // CHECK-NEXT: }
101
102 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias)
103 // CHECK-LOAD: call void @llvm.memcpy
104 // CHECK-LOAD-NEXT: ret void
105 // CHECK-LOAD-NEXT: }
106 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}([[SSS_INT]]* noalias, [[SSS_INT]]* noalias)
107 // CHECK-LOAD: call {{.*}}void [[INIT]](
108 // CHECK-LOAD-NEXT: ret void
109 // CHECK-LOAD-NEXT: }
110
111 template <typename T>
112 T foo(T a) {
113 #pragma omp declare reduction(fun : T : omp_out += omp_in) initializer(omp_priv = 15 * omp_orig)
114   {
115 #pragma omp declare reduction(fun : T : omp_out /= omp_in) initializer(omp_priv = 11 - omp_orig)
116   }
117   return a;
118 }
119
120 struct Summary {
121   void merge(const Summary& other) {}
122 };
123
124 template <typename K>
125 void work() {
126   Summary global_summary;
127 #pragma omp declare reduction(+ : Summary : omp_out.merge(omp_in))
128 #pragma omp parallel for reduction(+ : global_summary)
129   for (int k = 1; k <= 100; ++k) {
130   }
131 }
132
133 struct A {};
134
135
136 // CHECK-LABEL: @main
137 int main() {
138   int i = 0;
139   SSS<int> sss;
140 #pragma omp parallel reduction(SSS < int > ::fun : i)
141   {
142     i += 1;
143   }
144 #pragma omp parallel reduction(::fun : sss)
145   {
146   }
147 #pragma omp declare reduction(fun : SSS < int > : init(omp_out, omp_in))
148 #pragma omp parallel reduction(fun : sss)
149   {
150   }
151   // CHECK: call {{.*}}void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
152   // CHECK: call {{.*}}void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
153   // CHECK: call {{.*}}void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call({{[^@]*}} @{{[^@]*}}[[REGION:@[^ ]+]]
154   // CHECK-LABEL: work
155   work<A>();
156   // CHECK-LABEL: foo
157   return foo(15);
158 }
159
160 // CHECK: define internal {{.*}}void [[REGION]](
161 // CHECK: [[SSS_PRIV:%.+]] = alloca %struct.SSS,
162 // CHECK: invoke {{.*}} @_ZN3SSSIiEC1Ev(%struct.SSS* [[SSS_PRIV]])
163 // CHECK-NOT: {{call |invoke }}
164 // CHECK: call {{.*}}i32 @__kmpc_reduce_nowait(
165
166 // CHECK-LABEL: i32 @{{.+}}foo{{[^(].+}}(i32
167 // CHECK-LOAD-LABEL: i32 @{{.+}}foo{{[^(].+}}(i32
168
169 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
170 // CHECK-LOAD: [[XOR:%.+]] = xor i32
171 // CHECK-LOAD-NEXT: store i32 [[XOR]], i32*
172 // CHECK-LOAD-NEXT: ret void
173 // CHECK-LOAD-NEXT: }
174
175 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
176 // CHECK-LOAD: [[ADD:%.+]] = add nsw i32 24,
177 // CHECK-LOAD-NEXT: store i32 [[ADD]], i32*
178 // CHECK-LOAD-NEXT: ret void
179 // CHECK-LOAD-NEXT: }
180
181 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
182 // CHECK: [[ADD:%.+]] = add nsw i32
183 // CHECK-NEXT: store i32 [[ADD]], i32*
184 // CHECK-NEXT: ret void
185 // CHECK-NEXT: }
186 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
187 // CHECK-LOAD: [[ADD:%.+]] = add nsw i32
188 // CHECK-LOAD-NEXT: store i32 [[ADD]], i32*
189 // CHECK-LOAD-NEXT: ret void
190 // CHECK-LOAD-NEXT: }
191
192 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
193 // CHECK: [[MUL:%.+]] = mul nsw i32 15,
194 // CHECK-NEXT: store i32 [[MUL]], i32*
195 // CHECK-NEXT: ret void
196 // CHECK-NEXT: }
197 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
198 // CHECK-LOAD: [[MUL:%.+]] = mul nsw i32 15,
199 // CHECK-LOAD-NEXT: store i32 [[MUL]], i32*
200 // CHECK-LOAD-NEXT: ret void
201 // CHECK-LOAD-NEXT: }
202
203 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
204 // CHECK: [[DIV:%.+]] = sdiv i32
205 // CHECK-NEXT: store i32 [[DIV]], i32*
206 // CHECK-NEXT: ret void
207 // CHECK-NEXT: }
208 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
209 // CHECK-LOAD: [[DIV:%.+]] = sdiv i32
210 // CHECK-LOAD-NEXT: store i32 [[DIV]], i32*
211 // CHECK-LOAD-NEXT: ret void
212 // CHECK-LOAD-NEXT: }
213
214 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
215 // CHECK: [[SUB:%.+]] = sub nsw i32 11,
216 // CHECK-NEXT: store i32 [[SUB]], i32*
217 // CHECK-NEXT: ret void
218 // CHECK-NEXT: }
219 // CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
220 // CHECK-LOAD: [[SUB:%.+]] = sub nsw i32 11,
221 // CHECK-LOAD-NEXT: store i32 [[SUB]], i32*
222 // CHECK-LOAD-NEXT: ret void
223 // CHECK-LOAD-NEXT: }
224
225 #endif