Skip to content

Commit 3d27eba

Browse files
committed
correctly diagnose duplicate 'tile' and 'collapse' clauses
After discussion, it is clear that we should do some funny-business around 'device_type' on 'tile' and 'collapse', so this patch implements that checking.
1 parent dcec016 commit 3d27eba

File tree

4 files changed

+81
-6
lines changed

4 files changed

+81
-6
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12921,6 +12921,9 @@ def err_acc_clause_routine_cannot_combine_same_device_type
1292112921
def err_acc_clause_routine_one_of_in_region
1292212922
: Error<"OpenACC 'routine' construct must have at least one 'gang', 'seq', "
1292312923
"'vector', or 'worker' clause that applies to each 'device_type'">;
12924+
def err_acc_clause_since_last_device_type
12925+
: Error<"OpenACC '%0' clause cannot appear more than once on a '%1' "
12926+
"directive %select{|in a 'device_type' region}2}">;
1292412927

1292512928
def err_acc_reduction_num_gangs_conflict
1292612929
: Error<"OpenACC '%1' clause %select{|with more than 1 argument }0may not "

clang/lib/Sema/SemaOpenACCClause.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,33 @@ class SemaOpenACCClauseVisitor {
286286
return true;
287287
}
288288

289+
// For 'tile' and 'collapse', only allow 1 per 'device_type'.
290+
template <typename TheClauseTy>
291+
bool DisallowSinceLastDeviceType(SemaOpenACC::OpenACCParsedClause &Clause) {
292+
auto LastDeviceTypeItr =
293+
std::find_if(ExistingClauses.rbegin(), ExistingClauses.rend(),
294+
llvm::IsaPred<OpenACCDeviceTypeClause>);
295+
296+
auto Last = std::find_if(ExistingClauses.rbegin(), LastDeviceTypeItr,
297+
llvm::IsaPred<TheClauseTy>);
298+
299+
if (Last == LastDeviceTypeItr)
300+
return false;
301+
302+
SemaRef.Diag(Clause.getBeginLoc(),
303+
diag::err_acc_clause_since_last_device_type)
304+
<< Clause.getClauseKind() << Clause.getDirectiveKind()
305+
<< (LastDeviceTypeItr != ExistingClauses.rend());
306+
SemaRef.Diag((*Last)->getBeginLoc(), diag::note_acc_previous_clause_here);
307+
308+
if (LastDeviceTypeItr != ExistingClauses.rend())
309+
SemaRef.Diag((*LastDeviceTypeItr)->getBeginLoc(),
310+
diag::note_acc_previous_clause_here);
311+
312+
// TODO: DIAG
313+
return true;
314+
}
315+
289316
public:
290317
SemaOpenACCClauseVisitor(SemaOpenACC &S,
291318
ArrayRef<const OpenACCClause *> ExistingClauses)
@@ -342,6 +369,9 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitDefaultClause(
342369
OpenACCClause *SemaOpenACCClauseVisitor::VisitTileClause(
343370
SemaOpenACC::OpenACCParsedClause &Clause) {
344371

372+
if (DisallowSinceLastDeviceType<OpenACCTileClause>(Clause))
373+
return nullptr;
374+
345375
llvm::SmallVector<Expr *> NewSizeExprs;
346376

347377
// Make sure these are all positive constant expressions or *.
@@ -1503,6 +1533,9 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitReductionClause(
15031533
OpenACCClause *SemaOpenACCClauseVisitor::VisitCollapseClause(
15041534
SemaOpenACC::OpenACCParsedClause &Clause) {
15051535

1536+
if (DisallowSinceLastDeviceType<OpenACCCollapseClause>(Clause))
1537+
return nullptr;
1538+
15061539
ExprResult LoopCount = SemaRef.CheckCollapseLoopCount(Clause.getLoopCount());
15071540

15081541
if (!LoopCount.isUsable())

clang/test/SemaOpenACC/loop-construct-collapse-clause.cpp

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ void only_for_loops() {
1414

1515
}
1616

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(int i = 0; i < 5; ++i);
22+
}
23+
1724
constexpr int three() { return 3; }
1825
constexpr int one() { return 1; }
1926
constexpr int neg() { return -1; }
@@ -497,12 +504,12 @@ template<unsigned N>
497504
void allow_multiple_collapse_templ() {
498505
// expected-error@+2{{'collapse' clause specifies a loop count greater than the number of available loops}}
499506
// expected-note@+1{{active 'collapse' clause defined here}}
500-
#pragma acc loop collapse(N) collapse(N+1)
507+
#pragma acc loop collapse(N) device_type(*) collapse(N+1)
501508
for(unsigned i = 0; i < 5; ++i)
502509
for(unsigned j = 0; j < 5; ++j);
503510
// expected-error@+2{{'collapse' clause specifies a loop count greater than the number of available loops}}
504511
// expected-note@+1{{active 'collapse' clause defined here}}
505-
#pragma acc loop collapse(N+1) collapse(N)
512+
#pragma acc loop collapse(N+1) device_type(*) collapse(N)
506513
for(unsigned i = 0; i < 5; ++i)
507514
for(unsigned j = 0; j < 5; ++j);
508515
}
@@ -511,12 +518,25 @@ void allow_multiple_collapse() {
511518

512519
// expected-error@+2{{'collapse' clause specifies a loop count greater than the number of available loops}}
513520
// expected-note@+1{{active 'collapse' clause defined here}}
514-
#pragma acc loop collapse(2) collapse(3)
521+
#pragma acc loop collapse(2) device_type(*) collapse(3)
515522
for(unsigned i = 0; i < 5; ++i)
516523
for(unsigned j = 0; j < 5; ++j);
517524
// expected-error@+2{{'collapse' clause specifies a loop count greater than the number of available loops}}
518525
// expected-note@+1{{active 'collapse' clause defined here}}
519-
#pragma acc loop collapse(3) collapse(2)
526+
#pragma acc loop collapse(3) device_type(*) collapse(2)
527+
for(unsigned i = 0; i < 5; ++i)
528+
for(unsigned j = 0; j < 5; ++j);
529+
}
530+
531+
void no_dupes_since_last_device_type() {
532+
// expected-error@+3{{OpenACC 'collapse' clause cannot appear more than once on a 'loop' directive in a 'device_type' region}}
533+
// expected-note@+2{{previous clause is here}}
534+
// expected-note@+1{{previous clause is here}}
535+
#pragma acc loop collapse(1) device_type(*) collapse(1) collapse(2)
536+
for(unsigned i = 0; i < 5; ++i)
537+
for(unsigned j = 0; j < 5; ++j);
538+
539+
#pragma acc loop collapse(1) device_type(*) collapse(1) device_type(nvidia) collapse(2)
520540
for(unsigned i = 0; i < 5; ++i)
521541
for(unsigned j = 0; j < 5; ++j);
522542
}

clang/test/SemaOpenACC/loop-construct-tile-clause.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,13 @@ void only_for_loops() {
143143
do{}while(true);
144144
}
145145

146+
void only_one_on_loop() {
147+
// expected-error@+2{{OpenACC 'tile' clause cannot appear more than once on a 'loop' directive}}
148+
// expected-note@+1{{previous clause is here}}
149+
#pragma acc loop tile(1) tile(1)
150+
for(int i = 0; i < 5; ++i);
151+
}
152+
146153
template<unsigned Val>
147154
void depth_too_high_templ() {
148155
// expected-error@+1{{'tile' clause specifies a loop count greater than the number of available loops}}
@@ -380,13 +387,13 @@ void intervening() {
380387
void use_largest_tile() {
381388
// expected-error@+2{{'tile' clause specifies a loop count greater than the number of available loops}}
382389
// expected-note@+1{{active 'tile' clause defined here}}
383-
#pragma acc loop tile(1,2) tile (3,4,5)
390+
#pragma acc loop tile(1,2) device_type(*) tile (3,4,5)
384391
for(int i = 0; i < 5; ++i)
385392
for (int j = 0; j < 5; ++j);
386393

387394
// expected-error@+2{{'tile' clause specifies a loop count greater than the number of available loops}}
388395
// expected-note@+1{{active 'tile' clause defined here}}
389-
#pragma acc loop tile (3,4,5) tile(1,2)
396+
#pragma acc loop tile (3,4,5) device_type(*) tile(1,2)
390397
for(int i = 0; i < 5; ++i)
391398
for (int j = 0; j < 5; ++j);
392399
}
@@ -401,3 +408,15 @@ void collapse_tile_depth() {
401408
for(int j = 0; j < 5; ++j);
402409
}
403410
}
411+
void no_dupes_since_last_device_type() {
412+
// expected-error@+3{{OpenACC 'tile' clause cannot appear more than once on a 'loop' directive in a 'device_type' region}}
413+
// expected-note@+2{{previous clause is here}}
414+
// expected-note@+1{{previous clause is here}}
415+
#pragma acc loop tile(1) device_type(*) tile(1) tile(2)
416+
for(unsigned i = 0; i < 5; ++i)
417+
for(unsigned j = 0; j < 5; ++j);
418+
419+
#pragma acc loop tile(1) device_type(*) tile(1) device_type(nvidia) tile(2)
420+
for(unsigned i = 0; i < 5; ++i)
421+
for(unsigned j = 0; j < 5; ++j);
422+
}

0 commit comments

Comments
 (0)