diff --git a/flang/lib/Semantics/canonicalize-acc.cpp b/flang/lib/Semantics/canonicalize-acc.cpp --- a/flang/lib/Semantics/canonicalize-acc.cpp +++ b/flang/lib/Semantics/canonicalize-acc.cpp @@ -64,6 +64,8 @@ std::size_t tileArgNb = listTileExpr.size(); const auto &outer{std::get>(x.t)}; + if (outer->IsDoConcurrent()) + return; // Tile is not allowed on DO CONURRENT for (const parser::DoConstruct *loop{&*outer}; loop && tileArgNb > 0; --tileArgNb) { const auto &block{std::get(loop->t)}; @@ -82,6 +84,27 @@ } } + // Check constraint on line 1835 in Section 2.9 + // A tile and collapse clause may not appear on loop that is associated with + // do concurrent. + template + void CheckDoConcurrentClauseRestriction(const C &x) { + const auto &doCons{std::get>(x.t)}; + if (!doCons->IsDoConcurrent()) + return; + const auto &beginLoopDirective = std::get(x.t); + const auto &accClauseList = + std::get(beginLoopDirective.t); + for (const auto &clause : accClauseList.v) { + if (std::holds_alternative(clause.u) || + std::holds_alternative(clause.u)) { + messages_.Say(beginLoopDirective.source, + "TILE and COLLAPSE clause may not appear on loop construct " + "associated with DO CONCURRENT"_err_en_US); + } + } + } + void RewriteOpenACCLoopConstruct(parser::OpenACCLoopConstruct &x, parser::Block &block, parser::Block::iterator it) { // Check the sequence of DoConstruct in the same iteration @@ -112,8 +135,12 @@ "DO loop after the %s directive must have loop control"_err_en_US, parser::ToUpperCaseLetters(dir.source.ToString())); } + + CheckDoConcurrentClauseRestriction(x); CheckTileClauseRestriction(x); + return; // found do-loop } } @@ -163,8 +190,12 @@ "DO loop after the %s directive must have loop control"_err_en_US, parser::ToUpperCaseLetters(dir.source.ToString())); } + + CheckDoConcurrentClauseRestriction(x); CheckTileClauseRestriction(x); + return; // found do-loop } } diff --git a/flang/test/Semantics/acc-canonicalization-validity.f90 b/flang/test/Semantics/acc-canonicalization-validity.f90 --- a/flang/test/Semantics/acc-canonicalization-validity.f90 +++ b/flang/test/Semantics/acc-canonicalization-validity.f90 @@ -13,6 +13,7 @@ integer :: i, j integer :: N = 256 real(8) :: a(256) + real(8) :: aa(256, 256) !ERROR: A DO loop must follow the LOOP directive !$acc loop @@ -106,4 +107,20 @@ a(i) = 3.14 end do + !$acc parallel + !ERROR: TILE and COLLAPSE clause may not appear on loop construct associated with DO CONCURRENT + !$acc loop collapse(2) + do concurrent (i = 1:N, j = 1:N) + aa(i, j) = 3.14 + end do + !$acc end parallel + + !$acc parallel + !ERROR: TILE and COLLAPSE clause may not appear on loop construct associated with DO CONCURRENT + !$acc loop tile(2, 2) + do concurrent (i = 1:N, j = 1:N) + aa(i, j) = 3.14 + end do + !$acc end parallel + end program openacc_clause_validity diff --git a/flang/test/Semantics/acc-clause-validity.f90 b/flang/test/Semantics/acc-clause-validity.f90 --- a/flang/test/Semantics/acc-clause-validity.f90 +++ b/flang/test/Semantics/acc-clause-validity.f90 @@ -219,6 +219,14 @@ end do !$acc end parallel + !$acc parallel + !ERROR: SEQ and AUTO clauses are mutually exclusive and may not appear on the same LOOP directive + !$acc loop auto seq + do i = 1, N + a(i) = 3.14 + end do + !$acc end parallel + !$acc parallel !$acc loop tile(2) do i = 1, N @@ -287,6 +295,14 @@ end do !$acc end parallel + !$acc parallel + !ERROR: At most one VECTOR clause can appear on the LOOP directive + !$acc loop vector vector(128) + do i = 1, N + a(i) = 3.14 + end do + !$acc end parallel + !$acc parallel !$acc loop vector do i = 1, N @@ -315,6 +331,14 @@ end do !$acc end parallel + !$acc parallel + !ERROR: At most one WORKER clause can appear on the LOOP directive + !$acc loop worker worker(10) + do i = 1, N + a(i) = 3.14 + end do + !$acc end parallel + !$acc parallel !$acc loop worker do i = 1, N @@ -343,6 +367,14 @@ end do !$acc end parallel + !$acc parallel + !ERROR: At most one GANG clause can appear on the LOOP directive + !$acc loop gang gang(gang_size) + do i = 1, N + a(i) = 3.14 + end do + !$acc end parallel + !$acc parallel !$acc loop gang(gang_size) do i = 1, N @@ -528,6 +560,22 @@ end do !$acc end parallel + !$acc parallel + !ERROR: Clause WORKER is not allowed if clause SEQ appears on the LOOP directive + !$acc loop worker seq + do i = 1, N + a(i) = 3.14 + end do + !$acc end parallel + + !$acc parallel + !ERROR: Clause VECTOR is not allowed if clause SEQ appears on the LOOP directive + !$acc loop vector seq + do i = 1, N + a(i) = 3.14 + end do + !$acc end parallel + !ERROR: Clause IF is not allowed after clause DEVICE_TYPE on the PARALLEL directive !$acc parallel device_type(*) if(.TRUE.) !$acc loop