xref: /llvm-project/clang/test/SemaOpenACC/loop-construct-gang-clause.cpp (revision 3a4b9f38915625c68c78b62de48a3de8b97c5043)
1 // RUN: %clang_cc1 %s -fopenacc -verify
2 
3 struct S{};
4 struct Converts{
5   operator int();
6 };
7 
8 template<typename T, unsigned Zero, unsigned Two, unsigned Four>
9 void ParallelOrOrphanTempl() {
10   T i;
11   // expected-error@+1{{'num' argument on 'gang' clause is not permitted on an orphaned 'loop' construct}}
12 #pragma acc loop gang(i)
13   for(int i = 0; i < 5; ++i);
14   // expected-error@+1{{'num' argument on 'gang' clause is not permitted on an orphaned 'loop' construct}}
15 #pragma acc loop gang(num:i)
16   for(int i = 0; i < 5; ++i);
17 
18   // expected-error@+2{{'num' argument on 'gang' clause is not permitted on a 'loop' construct associated with a 'parallel' compute construct}}
19 #pragma acc parallel
20 #pragma acc loop gang(i)
21   for(int i = 0; i < 5; ++i);
22 
23   // expected-error@+2{{'num' argument on 'gang' clause is not permitted on a 'loop' construct associated with a 'parallel' compute construct}}
24 #pragma acc parallel
25 #pragma acc loop gang(num:i)
26   for(int i = 0; i < 5; ++i);
27 
28   // expected-error@+1{{argument to 'gang' clause dimension must be a constant expression}}
29 #pragma acc loop gang(dim:i)
30   for(int i = 0; i < 5; ++i);
31 
32   // expected-error@+2{{argument to 'gang' clause dimension must be a constant expression}}
33 #pragma acc parallel
34 #pragma acc loop gang(dim:i)
35   for(int i = 0; i < 5; ++i);
36 
37   // expected-error@+1{{argument to 'gang' clause dimension must be 1, 2, or 3: evaluated to 0}}
38 #pragma acc loop gang(dim:Zero)
39   for(int i = 0; i < 5; ++i);
40 
41   // expected-error@+2{{argument to 'gang' clause dimension must be 1, 2, or 3: evaluated to 0}}
42 #pragma acc parallel
43 #pragma acc loop gang(dim:Zero)
44   for(int i = 0; i < 5; ++i);
45 
46   // expected-error@+1{{argument to 'gang' clause dimension must be 1, 2, or 3: evaluated to 4}}
47 #pragma acc loop gang(dim:Four)
48   for(int i = 0; i < 5; ++i);
49 
50   // expected-error@+2{{argument to 'gang' clause dimension must be 1, 2, or 3: evaluated to 4}}
51 #pragma acc parallel
52 #pragma acc loop gang(dim:Four)
53   for(int i = 0; i < 5; ++i);
54 
55 #pragma acc loop gang(static:i) gang(dim:Two)
56   for(int i = 0; i < 5; ++i);
57 
58 #pragma acc parallel
59 #pragma acc loop gang(dim:Two) gang(static:*)
60   for(int i = 0; i < 5; ++i);
61 
62 #pragma acc parallel
63 #pragma acc loop gang(dim:Two, static:i)
64   for(int i = 0; i < 5; ++i);
65 
66   // expected-error@+4{{OpenACC 'gang' clause may have at most one 'static' argument}}
67   // expected-note@+3{{previous expression is here}}
68   // expected-error@+2{{OpenACC 'gang' clause may have at most one 'dim' argument}}
69   // expected-note@+1{{previous expression is here}}
70 #pragma acc loop gang(static:i, static:i, dim:Two, dim:1)
71   for(int i = 0; i < 5; ++i);
72 }
73 
74 void ParallelOrOrphan() {
75   ParallelOrOrphanTempl<int, 0, 2, 4>(); // expected-note{{in instantiation of function template}}
76 
77   int i;
78   // expected-error@+1{{'num' argument on 'gang' clause is not permitted on an orphaned 'loop' construct}}
79 #pragma acc loop gang(i)
80   for(int i = 0; i < 5; ++i);
81   // expected-error@+1{{'num' argument on 'gang' clause is not permitted on an orphaned 'loop' construct}}
82 #pragma acc loop gang(num:i)
83   for(int i = 0; i < 5; ++i);
84 
85   // expected-error@+2{{'num' argument on 'gang' clause is not permitted on a 'loop' construct associated with a 'parallel' compute construct}}
86 #pragma acc parallel
87 #pragma acc loop gang(i)
88   for(int i = 0; i < 5; ++i);
89 
90   // expected-error@+2{{'num' argument on 'gang' clause is not permitted on a 'loop' construct associated with a 'parallel' compute construct}}
91 #pragma acc parallel
92 #pragma acc loop gang(num:i)
93   for(int i = 0; i < 5; ++i);
94 
95   // expected-error@+1{{argument to 'gang' clause dimension must be a constant expression}}
96 #pragma acc loop gang(dim:i)
97   for(int i = 0; i < 5; ++i);
98 
99   // expected-error@+2{{argument to 'gang' clause dimension must be a constant expression}}
100 #pragma acc parallel
101 #pragma acc loop gang(dim:i)
102   for(int i = 0; i < 5; ++i);
103 
104   // expected-error@+1{{argument to 'gang' clause dimension must be 1, 2, or 3: evaluated to 0}}
105 #pragma acc loop gang(dim:0)
106   for(int i = 0; i < 5; ++i);
107 
108   // expected-error@+2{{argument to 'gang' clause dimension must be 1, 2, or 3: evaluated to 0}}
109 #pragma acc parallel
110 #pragma acc loop gang(dim:0)
111   for(int i = 0; i < 5; ++i);
112 
113   // expected-error@+1{{argument to 'gang' clause dimension must be 1, 2, or 3: evaluated to 4}}
114 #pragma acc loop gang(dim:4)
115   for(int i = 0; i < 5; ++i);
116 
117   // expected-error@+2{{argument to 'gang' clause dimension must be 1, 2, or 3: evaluated to 4}}
118 #pragma acc parallel
119 #pragma acc loop gang(dim:4)
120   for(int i = 0; i < 5; ++i);
121 
122 #pragma acc loop gang(static:i) gang(dim:2)
123   for(int i = 0; i < 5; ++i);
124 
125 #pragma acc parallel
126 #pragma acc loop gang(dim:2) gang(static:i)
127   for(int i = 0; i < 5; ++i);
128 
129   S s;
130   // expected-error@+2{{OpenACC clause 'gang' requires expression of integer type ('S' invalid)}}
131 #pragma acc parallel
132 #pragma acc loop gang(dim:2) gang(static:s)
133   for(int i = 0; i < 5; ++i);
134 
135   Converts C;
136 #pragma acc parallel
137 #pragma acc loop gang(dim:2) gang(static:C)
138   for(int i = 0; i < 5; ++i);
139 }
140 
141 template<typename SomeS, typename SomeC, typename Int>
142 void StaticIsIntegralTempl() {
143   SomeS s;
144   // expected-error@+2{{OpenACC clause 'gang' requires expression of integer type ('S' invalid)}}
145 #pragma acc parallel
146 #pragma acc loop gang(dim:2) gang(static:s)
147   for(int i = 0; i < 5; ++i);
148 
149   SomeC C;
150 #pragma acc parallel
151 #pragma acc loop gang(dim:2) gang(static:C)
152   for(int i = 0; i < 5; ++i);
153   Int i;
154 #pragma acc parallel
155 #pragma acc loop gang(dim:2) gang(static:i)
156   for(int i = 0; i < 5; ++i);
157 
158 #pragma acc parallel
159 #pragma acc loop gang(dim:2) gang(static:*)
160   for(int i = 0; i < 5; ++i);
161 }
162 
163 void StaticIsIntegral() {
164   StaticIsIntegralTempl<S, Converts, int>();// expected-note{{in instantiation of function template}}
165 
166   S s;
167   // expected-error@+2{{OpenACC clause 'gang' requires expression of integer type ('S' invalid)}}
168 #pragma acc parallel
169 #pragma acc loop gang(dim:2) gang(static:s)
170   for(int i = 0; i < 5; ++i);
171 
172   Converts C;
173 #pragma acc parallel
174 #pragma acc loop gang(dim:2) gang(static:C)
175   for(int i = 0; i < 5; ++i);
176 }
177 
178 template<unsigned I>
179 void SerialTempl() {
180   // expected-error@+2{{'num' argument on 'gang' clause is not permitted on a 'loop' construct associated with a 'serial' compute construct}}
181 #pragma acc serial
182 #pragma acc loop gang(I)
183   for(int i = 0; i < 5; ++i);
184 
185   // expected-error@+2{{'num' argument on 'gang' clause is not permitted on a 'loop' construct associated with a 'serial' compute construct}}
186 #pragma acc serial
187 #pragma acc loop gang(num:I)
188   for(int i = 0; i < 5; ++i);
189 
190   // expected-error@+2{{'dim' argument on 'gang' clause is not permitted on a 'loop' construct associated with a 'serial' compute construct}}
191 #pragma acc serial
192 #pragma acc loop gang(dim:I)
193   for(int i = 0; i < 5; ++i);
194 
195 #pragma acc serial
196 #pragma acc loop gang(static:I)
197   for(int i = 0; i < 5; ++i);
198 }
199 
200 void Serial() {
201   SerialTempl<2>();
202 
203   // expected-error@+2{{'num' argument on 'gang' clause is not permitted on a 'loop' construct associated with a 'serial' compute construct}}
204 #pragma acc serial
205 #pragma acc loop gang(1)
206   for(int i = 0; i < 5; ++i);
207 
208   // expected-error@+2{{'num' argument on 'gang' clause is not permitted on a 'loop' construct associated with a 'serial' compute construct}}
209 #pragma acc serial
210 #pragma acc loop gang(num:1)
211   for(int i = 0; i < 5; ++i);
212 
213   // expected-error@+2{{'dim' argument on 'gang' clause is not permitted on a 'loop' construct associated with a 'serial' compute construct}}
214 #pragma acc serial
215 #pragma acc loop gang(dim:1)
216   for(int i = 0; i < 5; ++i);
217 
218 #pragma acc serial
219 #pragma acc loop gang(static:1)
220   for(int i = 0; i < 5; ++i);
221 
222   int i;
223 
224 #pragma acc serial
225 #pragma acc loop gang(static:i)
226   for(int i = 0; i < 5; ++i);
227 }
228 
229 template<typename T>
230 void KernelsTempl() {
231   T t;
232   // expected-error@+2{{'dim' argument on 'gang' clause is not permitted on a 'loop' construct associated with a 'kernels' compute construct}}
233 #pragma acc kernels
234 #pragma acc loop gang(dim:t)
235   for(int i = 0; i < 5; ++i);
236 
237 #pragma acc kernels
238 #pragma acc loop gang(static:t)
239   for(int i = 0; i < 5; ++i);
240 
241   // expected-error@+3{{'num' argument to 'gang' clause not allowed on a 'loop' construct associated with a 'kernels' construct that has a 'num_gangs' clause}}
242   // expected-note@+1{{previous clause is here}}
243 #pragma acc kernels num_gangs(t)
244 #pragma acc loop gang(t)
245   for(int i = 0; i < 5; ++i);
246 
247   // expected-error@+3{{'num' argument to 'gang' clause not allowed on a 'loop' construct associated with a 'kernels' construct that has a 'num_gangs' clause}}
248   // expected-note@+1{{previous clause is here}}
249 #pragma acc kernels num_gangs(t)
250 #pragma acc loop gang(num:t)
251   for(int i = 0; i < 5; ++i);
252 }
253 
254 void Kernels() {
255   KernelsTempl<unsigned>();
256 
257   // expected-error@+2{{'dim' argument on 'gang' clause is not permitted on a 'loop' construct associated with a 'kernels' compute construct}}
258 #pragma acc kernels
259 #pragma acc loop gang(dim:1)
260   for(int i = 0; i < 5; ++i);
261   unsigned t;
262 #pragma acc kernels
263 #pragma acc loop gang(static:t)
264   for(int i = 0; i < 5; ++i);
265 
266   // expected-error@+3{{'num' argument to 'gang' clause not allowed on a 'loop' construct associated with a 'kernels' construct that has a 'num_gangs' clause}}
267   // expected-note@+1{{previous clause is here}}
268 #pragma acc kernels num_gangs(1)
269 #pragma acc loop gang(1)
270   for(int i = 0; i < 5; ++i);
271 
272   // expected-error@+3{{'num' argument to 'gang' clause not allowed on a 'loop' construct associated with a 'kernels' construct that has a 'num_gangs' clause}}
273   // expected-note@+1{{previous clause is here}}
274 #pragma acc kernels num_gangs(1)
275 #pragma acc loop gang(num:1)
276   for(int i = 0; i < 5; ++i);
277 
278 #pragma acc kernels
279 #pragma acc loop gang(num:1)
280   for(int j = 0; j < 5; ++j) {
281     // expected-error@+2{{loop with a 'gang' clause may not exist in the region of a 'gang' clause on a 'kernels' construct}}
282     // expected-note@-3{{previous clause is here}}
283 #pragma acc loop gang(static:1)
284     for(int i = 0; i < 5; ++i);
285   }
286 
287 #pragma acc kernels
288 #pragma acc loop gang(num:1)
289   for(int j = 0; j < 5; ++j) {
290 #pragma acc loop worker(1) vector(1)
291     for(int i = 0; i < 5; ++i);
292   }
293 
294 #pragma acc kernels
295 #pragma acc loop gang(num:1)
296   for(int j = 0; j < 5; ++j) {
297     // allowed, intervening compute construct
298 #pragma acc serial
299 #pragma acc loop gang(static:1)
300     for(int i = 0; i < 5; ++i);
301   }
302 
303 #pragma acc kernels
304 #pragma acc loop gang(num:1)
305   for(int i = 0; i < 5; ++i);
306 
307   // OK, on a different 'loop', not in the assoc statement.
308 #pragma acc loop gang(static:1)
309   for(int i = 0; i < 5; ++i);
310 
311   // expected-error@+3{{OpenACC 'gang' clause may have at most one unnamed or 'num' argument}}
312   // expected-note@+2{{previous expression is here}}
313 #pragma acc kernels
314 #pragma acc loop gang(5, num:1)
315   for(int i = 0; i < 5; ++i);
316 
317   // expected-error@+3{{OpenACC 'gang' clause may have at most one unnamed or 'num' argument}}
318   // expected-note@+2{{previous expression is here}}
319 #pragma acc kernels
320 #pragma acc loop gang(num:5, 1)
321   for(int i = 0; i < 5; ++i);
322 
323   // expected-error@+3{{OpenACC 'gang' clause may have at most one unnamed or 'num' argument}}
324   // expected-note@+2{{previous expression is here}}
325 #pragma acc kernels
326 #pragma acc loop gang(num:5, num:1)
327   for(int i = 0; i < 5; ++i);
328 }
329 
330 void MaxOneEntry() {
331   // expected-error@+3{{OpenACC 'gang' clause may have at most one 'static' argument}}
332   // expected-note@+2{{previous expression is here}}
333 #pragma acc kernels
334 #pragma acc loop gang(static: 1, static:1)
335     for(int i = 0; i < 5; ++i);
336 
337 #pragma acc kernels
338 #pragma acc loop gang gang(static:1)
339     for(int i = 0; i < 5; ++i);
340 }
341 
342 
343