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