xref: /llvm-project/clang/test/SemaOpenACC/loop-construct-collapse-clause.cpp (revision bfc2dbe02e00f0023c0a2d58b53cdbd1f4139f02)
1 // RUN: %clang_cc1 %s -fopenacc -verify
2 
3 
4 void only_for_loops() {
5   // expected-error@+3{{OpenACC 'loop' construct can only be applied to a 'for' loop}}
6   // expected-note@+1{{'loop' construct is here}}
7 #pragma acc loop collapse(1)
8   while(true);
9 
10   // expected-error@+3{{OpenACC 'loop' construct can only be applied to a 'for' loop}}
11   // expected-note@+1{{'loop' construct is here}}
12 #pragma acc loop collapse(1)
13   do{}while(true);
14 
15 }
16 
17 void only_one_on_loop() {
18   // expected-error@+2{{OpenACC 'collapse' clause cannot appear more than once on a 'loop' directive}}
19   // expected-note@+1{{previous clause is here}}
20 #pragma acc loop collapse(1) collapse(1)
21   for(unsigned i = 0; i < 5; ++i);
22 }
23 
24 constexpr int three() { return 3; }
25 constexpr int one() { return 1; }
26 constexpr int neg() { return -1; }
27 constexpr int zero() { return 0; }
28 
29 struct NotConstexpr {
30   constexpr NotConstexpr(){};
31 
32   operator int(){ return 1; }
33 };
34 struct ConvertsNegative {
35   constexpr ConvertsNegative(){};
36 
37   constexpr operator int(){ return -1; }
38 };
39 struct ConvertsOne{
40   constexpr ConvertsOne(){};
41 
42   constexpr operator int(){ return 1; }
43 };
44 
45 struct ConvertsThree{
46   constexpr ConvertsThree(){};
47 
48   constexpr operator int(){ return 3; }
49 };
50 
51 template <typename T, int Val>
52 void negative_constexpr_templ() {
53   // expected-error@+3 2{{OpenACC 'collapse' clause loop count must be a positive integer value, evaluated to 0}}
54   // expected-note@#NCETN1{{in instantiation of function template specialization 'negative_constexpr_templ<int, -1>'}}
55   // expected-note@#NCET1{{in instantiation of function template specialization 'negative_constexpr_templ<int, 1>'}}
56 #pragma acc loop collapse(T{})
57   for(unsigned i = 0; i < 5; ++i)
58     for(unsigned j = 0; j < 5; ++j);
59 
60   // expected-error@+1{{OpenACC 'collapse' clause loop count must be a positive integer value, evaluated to -1}}
61 #pragma acc loop collapse(Val)
62   for(unsigned i = 0; i < 5; ++i)
63     for(unsigned j = 0; j < 5; ++j);
64 }
65 
66 void negative_constexpr(int i) {
67 #pragma acc loop collapse(2)
68   for(unsigned i = 0; i < 5; ++i)
69     for(unsigned j = 0; j < 5; ++j);
70 
71 #pragma acc loop collapse(1)
72   for(unsigned i = 0; i < 5; ++i)
73     for(unsigned j = 0; j < 5; ++j);
74 
75   // expected-error@+1{{OpenACC 'collapse' clause loop count must be a positive integer value, evaluated to 0}}
76 #pragma acc loop collapse(0)
77   for(unsigned i = 0; i < 5; ++i)
78     for(unsigned j = 0; j < 5; ++j);
79 
80   // expected-error@+1{{OpenACC 'collapse' clause loop count must be a positive integer value, evaluated to -1}}
81 #pragma acc loop collapse(-1)
82   for(unsigned i = 0; i < 5; ++i)
83     for(unsigned j = 0; j < 5; ++j);
84 
85 #pragma acc loop collapse(one())
86   for(unsigned i = 0; i < 5; ++i)
87     for(unsigned j = 0; j < 5; ++j);
88 
89   // expected-error@+1{{OpenACC 'collapse' clause loop count must be a positive integer value, evaluated to 0}}
90 #pragma acc loop collapse(zero())
91   for(unsigned i = 0; i < 5; ++i)
92     for(unsigned j = 0; j < 5; ++j);
93 
94   // expected-error@+1{{OpenACC 'collapse' clause loop count must be a positive integer value, evaluated to -1}}
95 #pragma acc loop collapse(neg())
96   for(unsigned i = 0; i < 5; ++i)
97     for(unsigned j = 0; j < 5; ++j);
98 
99   // expected-error@+1{{OpenACC 'collapse' clause loop count must be a constant expression}}
100 #pragma acc loop collapse(NotConstexpr{})
101   for(unsigned i = 0; i < 5; ++i)
102     for(unsigned j = 0; j < 5; ++j);
103 
104   // expected-error@+1{{OpenACC 'collapse' clause loop count must be a positive integer value, evaluated to -1}}
105 #pragma acc loop collapse(ConvertsNegative{})
106   for(unsigned i = 0; i < 5; ++i)
107     for(unsigned j = 0; j < 5; ++j);
108 
109 #pragma acc loop collapse(ConvertsOne{})
110   for(unsigned i = 0; i < 5; ++i)
111     for(unsigned j = 0; j < 5; ++j);
112 
113   negative_constexpr_templ<int, -1>(); // #NCETN1
114 
115   negative_constexpr_templ<int, 1>(); // #NCET1
116 }
117 
118 template<unsigned Val>
119 void depth_too_high_templ() {
120   // expected-error@+2{{'collapse' clause specifies a loop count greater than the number of available loops}}
121   // expected-note@+1{{active 'collapse' clause defined here}}
122 #pragma acc loop collapse(Val)
123   for(unsigned i = 0; i < 5; ++i)
124     for(unsigned j = 0; j < 5; ++j);
125 }
126 
127 void depth_too_high() {
128   depth_too_high_templ<3>(); // expected-note{{in instantiation of function template specialization}}
129 
130   // expected-error@+2{{'collapse' clause specifies a loop count greater than the number of available loops}}
131   // expected-note@+1{{active 'collapse' clause defined here}}
132 #pragma acc loop collapse(3)
133   for(unsigned i = 0; i < 5; ++i)
134     for(unsigned j = 0; j < 5; ++j);
135 
136   // expected-error@+2{{'collapse' clause specifies a loop count greater than the number of available loops}}
137   // expected-note@+1{{active 'collapse' clause defined here}}
138 #pragma acc loop collapse(three())
139   for(unsigned i = 0; i < 5; ++i)
140     for(unsigned j = 0; j < 5; ++j);
141 
142   // expected-error@+2{{'collapse' clause specifies a loop count greater than the number of available loops}}
143   // expected-note@+1{{active 'collapse' clause defined here}}
144 #pragma acc loop collapse(ConvertsThree{})
145   for(unsigned i = 0; i < 5; ++i)
146     for(unsigned j = 0; j < 5; ++j);
147 }
148 
149 template<typename T, unsigned Three>
150 void not_single_loop_templ() {
151   T Arr[5];
152   // expected-error@+2{{'collapse' clause specifies a loop count greater than the number of available loops}}
153   // expected-note@+1 2{{active 'collapse' clause defined here}}
154 #pragma acc loop collapse(3)
155   for(auto x : Arr) {
156     for(auto y : Arr){
157       do{}while(true); // expected-error{{do loop cannot appear in intervening code of a 'loop' with a 'collapse' clause}}
158     }
159   }
160 
161   // expected-error@+2{{'collapse' clause specifies a loop count greater than the number of available loops}}
162   // expected-note@+1 2{{active 'collapse' clause defined here}}
163 #pragma acc loop collapse(Three)
164   for(unsigned i = 0; i < 5; ++i) {
165     for(unsigned j = 0; j < 5; ++j) {
166       do{}while(true); // expected-error{{do loop cannot appear in intervening code of a 'loop' with a 'collapse' clause}}
167     }
168   }
169 
170 #pragma acc loop collapse(Three)
171   for(unsigned i = 0; i < 5; ++i) {
172     for(unsigned j = 0; j < 5; ++j) {
173       for(unsigned k = 0; k < 5;++k) {
174         do{}while(true);
175       }
176     }
177   }
178   // expected-error@+2{{'collapse' clause specifies a loop count greater than the number of available loops}}
179   // expected-note@+1 2{{active 'collapse' clause defined here}}
180 #pragma acc loop collapse(Three)
181   for(auto x : Arr) {
182     for(auto y: Arr) {
183       do{}while(true); // expected-error{{do loop cannot appear in intervening code of a 'loop' with a 'collapse' clause}}
184     }
185   }
186 
187 #pragma acc loop collapse(Three)
188   for(auto x : Arr) {
189     for(auto y: Arr) {
190       for(auto z: Arr) {
191         do{}while(true);
192       }
193     }
194   }
195 }
196 
197 void not_single_loop() {
198   not_single_loop_templ<int, 3>(); // expected-note{{in instantiation of function template}}
199 
200   // expected-note@+1{{active 'collapse' clause defined here}}
201 #pragma acc loop collapse(3)
202   for(unsigned i = 0; i < 5; ++i) {
203     for(unsigned j = 0; j < 5; ++j) {
204       for(unsigned k = 0; k < 5;++k);
205     }
206     while(true); // expected-error{{while loop cannot appear in intervening code of a 'loop' with a 'collapse' clause}}
207   }
208 
209   // expected-note@+1{{active 'collapse' clause defined here}}
210 #pragma acc loop collapse(3)
211   for(unsigned i = 0; i < 5; ++i) {
212     for(unsigned j = 0; j < 5; ++j) {
213       for(unsigned k = 0; k < 5;++k);
214     }
215     do{}while(true); // expected-error{{do loop cannot appear in intervening code of a 'loop' with a 'collapse' clause}}
216   }
217 
218   // expected-error@+2{{'collapse' clause specifies a loop count greater than the number of available loops}}
219   // expected-note@+1 2{{active 'collapse' clause defined here}}
220 #pragma acc loop collapse(3)
221   for(unsigned i = 0; i < 5; ++i) {
222     for(unsigned j = 0; j < 5; ++j) {
223       while(true); // expected-error{{while loop cannot appear in intervening code of a 'loop' with a 'collapse' clause}}
224     }
225   }
226   // expected-error@+2{{'collapse' clause specifies a loop count greater than the number of available loops}}
227   // expected-note@+1 2{{active 'collapse' clause defined here}}
228 #pragma acc loop collapse(3)
229   for(unsigned i = 0; i < 5; ++i) {
230     for(unsigned j = 0; j < 5; ++j) {
231       do{}while(true); // expected-error{{do loop cannot appear in intervening code of a 'loop' with a 'collapse' clause}}
232     }
233   }
234 
235 #pragma acc loop collapse(2)
236   for(unsigned i = 0; i < 5; ++i) {
237     for(unsigned j = 0; j < 5; ++j) {
238       do{}while(true);
239     }
240   }
241 #pragma acc loop collapse(2)
242   for(unsigned i = 0; i < 5; ++i) {
243     for(unsigned j = 0; j < 5; ++j) {
244       while(true);
245     }
246   }
247 
248   int Arr[5];
249   // expected-error@+2{{'collapse' clause specifies a loop count greater than the number of available loops}}
250   // expected-note@+1 2{{active 'collapse' clause defined here}}
251 #pragma acc loop collapse(3)
252   for(auto x : Arr) {
253     for(auto y : Arr){
254       do{}while(true); // expected-error{{do loop cannot appear in intervening code of a 'loop' with a 'collapse' clause}}
255     }
256   }
257 
258   // expected-note@+1 {{active 'collapse' clause defined here}}
259 #pragma acc loop collapse(3)
260   for(unsigned i = 0; i < 5; ++i) {
261     for(unsigned j = 0; j < 5; ++j) {
262       for(unsigned k = 0; k < 5;++k);
263     }
264     // expected-error@+1{{more than one for-loop in a loop associated with OpenACC 'loop' construct with a 'collapse' clause}}
265       for(unsigned k = 0; k < 5;++k);
266   }
267 
268   // expected-note@+1 {{active 'collapse' clause defined here}}
269 #pragma acc loop collapse(3)
270   for(unsigned i = 0; i < 5; ++i) {
271     for(unsigned j = 0; j < 5; ++j) {
272       for(unsigned k = 0; k < 5;++k);
273     // expected-error@+1{{more than one for-loop in a loop associated with OpenACC 'loop' construct with a 'collapse' clause}}
274       for(unsigned k = 0; k < 5;++k);
275     }
276   }
277 
278   for(unsigned k = 0; k < 5;++k);
279 #pragma acc loop collapse(3)
280   for(unsigned i = 0; i < 5; ++i) {
281     for(unsigned j = 0; j < 5; ++j) {
282       for(unsigned k = 0; k < 5;++k);
283     }
284   }
285 }
286 
287 template<unsigned Two, unsigned Three>
288 void no_other_directives() {
289 #pragma acc loop collapse(Two)
290   for(unsigned i = 0; i < 5; ++i) {
291     for(unsigned j = 0; j < 5; ++j) {// last loop associated with the top level.
292     // expected-error@+1{{'collapse' clause specifies a loop count greater than the number of available loops}}
293 #pragma acc loop collapse(Three) // expected-note 2{{active 'collapse' clause defined here}}
294       for(unsigned k = 0; k < 6;++k) {
295         for(unsigned l = 0; l < 5; ++l) {
296     // expected-error@+1{{OpenACC 'serial' construct cannot appear in intervening code of a 'loop' with a 'collapse' clause}}
297 #pragma acc serial
298           ;
299         }
300       }
301     }
302   }
303 #pragma acc loop collapse(Two)// expected-note{{active 'collapse' clause defined here}}
304   for(unsigned i = 0; i < 5; ++i) {
305     for(unsigned j = 0; j < 5; ++j) {// last loop associated with the top level.
306 #pragma acc loop collapse(Three)
307       for(unsigned k = 0; k < 6;++k) {
308         for(unsigned l = 0; l < 5; ++l) {
309           for(unsigned m = 0; m < 5; ++m);
310         }
311       }
312     }
313     // expected-error@+1{{OpenACC 'serial' construct cannot appear in intervening code of a 'loop' with a 'collapse' clause}}
314 #pragma acc serial
315           ;
316   }
317 }
318 
319 void no_other_directives() {
320   no_other_directives<2,3>(); // expected-note{{in instantiation of function template specialization}}
321 
322   // Ok, not inside the intervening list
323 #pragma acc loop collapse(2)
324   for(unsigned i = 0; i < 5; ++i) {
325     for(unsigned j = 0; j < 5; ++j) {
326     // expected-error@+1{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}}
327 #pragma acc data
328       ;
329     }
330   }
331   // expected-note@+1{{active 'collapse' clause defined here}}
332 #pragma acc loop collapse(2)
333   for(unsigned i = 0; i < 5; ++i) {
334     // expected-error@+2{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}}
335     // expected-error@+1{{OpenACC 'data' construct cannot appear in intervening code of a 'loop' with a 'collapse' clause}}
336 #pragma acc data
337     for(unsigned j = 0; j < 5; ++j) {
338     }
339   }
340 }
341 
342 void call();
343 
344 template<unsigned Two>
345 void intervening_without_force_templ() {
346   // expected-note@+1{{active 'collapse' clause defined here}}
347 #pragma acc loop collapse(2)
348   for(unsigned i = 0; i < 5; ++i) {
349     // expected-error@+1{{inner loops must be tightly nested inside a 'collapse' clause on a 'loop' construct}}
350     call();
351     for(unsigned j = 0; j < 5; ++j);
352   }
353 
354   // expected-note@+1{{active 'collapse' clause defined here}}
355 #pragma acc loop collapse(Two)
356   for(unsigned i = 0; i < 5; ++i) {
357     // expected-error@+1{{inner loops must be tightly nested inside a 'collapse' clause on a 'loop' construct}}
358     call();
359     for(unsigned j = 0; j < 5; ++j);
360   }
361 
362   // expected-note@+1{{active 'collapse' clause defined here}}
363 #pragma acc loop collapse(2)
364   for(unsigned i = 0; i < 5; ++i) {
365     for(unsigned j = 0; j < 5; ++j);
366     // expected-error@+1{{inner loops must be tightly nested inside a 'collapse' clause on a 'loop' construct}}
367     call();
368   }
369 
370 #pragma acc loop collapse(force:2)
371   for(unsigned i = 0; i < 5; ++i) {
372     call();
373     for(unsigned j = 0; j < 5; ++j);
374   }
375 
376 #pragma acc loop collapse(force:Two)
377   for(unsigned i = 0; i < 5; ++i) {
378     call();
379     for(unsigned j = 0; j < 5; ++j);
380   }
381 
382 
383 #pragma acc loop collapse(force:2)
384   for(unsigned i = 0; i < 5; ++i) {
385     for(unsigned j = 0; j < 5; ++j);
386     call();
387   }
388 
389 #pragma acc loop collapse(force:Two)
390   for(unsigned i = 0; i < 5; ++i) {
391     for(unsigned j = 0; j < 5; ++j);
392     call();
393   }
394 
395 #pragma acc loop collapse(Two)
396   for(unsigned i = 0; i < 5; ++i) {
397     for(unsigned j = 0; j < 5; ++j) {
398     call();
399     }
400   }
401 
402 #pragma acc loop collapse(Two)
403   for(unsigned i = 0; i < 5; ++i) {
404     {
405       {
406         for(unsigned j = 0; j < 5; ++j) {
407           call();
408         }
409       }
410     }
411   }
412 
413 #pragma acc loop collapse(force:Two)
414   for(unsigned i = 0; i < 5; ++i) {
415     for(unsigned j = 0; j < 5; ++j) {
416     call();
417     }
418   }
419 
420   // expected-note@+1{{active 'collapse' clause defined here}}
421 #pragma acc loop collapse(Two)
422   for(unsigned i = 0; i < 5; ++i) {
423     for(unsigned j = 0; j < 5; ++j);
424     // expected-error@+1{{inner loops must be tightly nested inside a 'collapse' clause on a 'loop' construct}}
425     call();
426   }
427 
428 #pragma acc loop collapse(2)
429   // expected-error@+2{{OpenACC 'loop' construct must have a terminating condition}}
430   // expected-note@-2{{'loop' construct is here}}
431   for(int i = 0;;++i)
432   // expected-error@+2{{OpenACC 'loop' construct must have a terminating condition}}
433   // expected-note@-5{{'loop' construct is here}}
434     for(int j = 0;;++j)
435       for(;;);
436 }
437 
438 void intervening_without_force() {
439   intervening_without_force_templ<2>(); // expected-note{{in instantiation of function template specialization}}
440   // expected-note@+1{{active 'collapse' clause defined here}}
441 #pragma acc loop collapse(2)
442   for(unsigned i = 0; i < 5; ++i) {
443     // expected-error@+1{{inner loops must be tightly nested inside a 'collapse' clause on a 'loop' construct}}
444     call();
445     for(unsigned j = 0; j < 5; ++j);
446   }
447 
448   // expected-note@+1{{active 'collapse' clause defined here}}
449 #pragma acc loop collapse(2)
450   for(unsigned i = 0; i < 5; ++i) {
451     for(unsigned j = 0; j < 5; ++j);
452     // expected-error@+1{{inner loops must be tightly nested inside a 'collapse' clause on a 'loop' construct}}
453     call();
454   }
455 
456   // The below two are fine, as they use the 'force' tag.
457 #pragma acc loop collapse(force:2)
458   for(unsigned i = 0; i < 5; ++i) {
459     call();
460     for(unsigned j = 0; j < 5; ++j);
461   }
462 
463 #pragma acc loop collapse(force:2)
464   for(unsigned i = 0; i < 5; ++i) {
465     for(unsigned j = 0; j < 5; ++j);
466     call();
467   }
468 
469 #pragma acc loop collapse(2)
470   for(unsigned i = 0; i < 5; ++i) {
471     for(unsigned j = 0; j < 5; ++j) {
472     call();
473     }
474   }
475 #pragma acc loop collapse(2)
476   for(unsigned i = 0; i < 5; ++i) {
477     {
478       {
479         for(unsigned j = 0; j < 5; ++j) {
480           call();
481         }
482       }
483     }
484   }
485 
486 #pragma acc loop collapse(force:2)
487   for(unsigned i = 0; i < 5; ++i) {
488     for(unsigned j = 0; j < 5; ++j) {
489     call();
490     }
491   }
492 
493 #pragma acc loop collapse(2)
494   // expected-error@+2{{OpenACC 'loop' construct must have a terminating condition}}
495   // expected-note@-2{{'loop' construct is here}}
496   for(int i = 0;;++i)
497   // expected-error@+2{{OpenACC 'loop' construct must have a terminating condition}}
498   // expected-note@-5{{'loop' construct is here}}
499     for(int j = 0;;++j)
500       for(;;);
501 }
502 
503