diff --git a/flang/docs/OpenACC.md b/flang/docs/OpenACC.md new file mode 100644 --- /dev/null +++ b/flang/docs/OpenACC.md @@ -0,0 +1,17 @@ + + +# OpenACC in Flang + +```eval_rst +.. contents:: + :local: +``` + +## Intentional deviation from the specification +* The end directive for combined construct can omit the `loop` keyword. diff --git a/flang/lib/Parser/executable-parsers.cpp b/flang/lib/Parser/executable-parsers.cpp --- a/flang/lib/Parser/executable-parsers.cpp +++ b/flang/lib/Parser/executable-parsers.cpp @@ -50,8 +50,7 @@ construct(indirect(forallConstruct)), construct(indirect(ompEndLoopDirective)), construct(indirect(openmpConstruct)), - construct(indirect(accEndCombinedDirective)), - construct(indirect(openaccConstruct)), + construct(indirect(Parser{})), construct(indirect(compilerDirective)))}; // R510 execution-part-construct -> diff --git a/flang/lib/Parser/openacc-parsers.cpp b/flang/lib/Parser/openacc-parsers.cpp --- a/flang/lib/Parser/openacc-parsers.cpp +++ b/flang/lib/Parser/openacc-parsers.cpp @@ -228,10 +228,19 @@ construct(Parser{}), construct(Parser{}))) -TYPE_PARSER(startAccLine >> sourced(construct(sourced( - "END"_tok >> Parser{})))) +TYPE_PARSER(startAccLine >> + sourced(construct(sourced("END"_tok >> + construct("KERNELS"_tok >> maybe("LOOP"_tok) >> + pure(llvm::acc::Directive::ACCD_kernels_loop) || + "PARALLEL"_tok >> maybe("LOOP"_tok) >> + pure(llvm::acc::Directive::ACCD_parallel_loop) || + "SERIAL"_tok >> maybe("LOOP"_tok) >> + pure(llvm::acc::Directive::ACCD_serial_loop)))))) TYPE_PARSER(construct( - sourced(Parser{} / endAccLine))) + sourced(Parser{} / endAccLine), + withMessage("A DO loop must follow the combined construct"_err_en_US, + Parser{}), + maybe(Parser{} / endAccLine))) } // namespace Fortran::parser diff --git a/flang/lib/Parser/type-parsers.h b/flang/lib/Parser/type-parsers.h --- a/flang/lib/Parser/type-parsers.h +++ b/flang/lib/Parser/type-parsers.h @@ -132,7 +132,6 @@ constexpr Parser containsStmt; // R1543 constexpr Parser compilerDirective; constexpr Parser openaccConstruct; -constexpr Parser accEndCombinedDirective; constexpr Parser openaccDeclarativeConstruct; constexpr Parser openmpConstruct; constexpr Parser openmpDeclarativeConstruct; 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 @@ -169,6 +169,15 @@ parser::Block::iterator nextIt; auto &beginDir{std::get(x.t)}; auto &dir{std::get(beginDir.t)}; + auto &doConstruct{std::get>(x.t)}; + + if (doConstruct) { + CheckDoConcurrentClauseRestriction(x); + CheckTileClauseRestriction(x); + return; + } nextIt = it; if (++nextIt != block.end()) { diff --git a/flang/test/Semantics/OpenACC/acc-canonicalization-validity.f90 b/flang/test/Semantics/OpenACC/acc-canonicalization-validity.f90 --- a/flang/test/Semantics/OpenACC/acc-canonicalization-validity.f90 +++ b/flang/test/Semantics/OpenACC/acc-canonicalization-validity.f90 @@ -24,27 +24,6 @@ do end do - !ERROR: A DO loop must follow the PARALLEL LOOP directive - !$acc parallel loop - i = 1 - - !ERROR: A DO loop must follow the KERNELS LOOP directive - !$acc kernels loop - i = 1 - - !ERROR: A DO loop must follow the SERIAL LOOP directive - !$acc serial loop - i = 1 - - !ERROR: The END PARALLEL LOOP directive must follow the DO loop associated with the loop construct - !$acc end parallel loop - - !ERROR: The END KERNELS LOOP directive must follow the DO loop associated with the loop construct - !$acc end kernels loop - - !ERROR: The END SERIAL LOOP directive must follow the DO loop associated with the loop construct - !$acc end serial loop - !$acc parallel loop do i = 1, N a(i) = 3.14 @@ -78,17 +57,17 @@ end do !$acc end serial loop - !ERROR: DO loop after the PARALLEL LOOP directive must have loop control + !!ERROR: DO loop after the PARALLEL LOOP directive must have loop control !$acc parallel loop do end do - !ERROR: DO loop after the KERNELS LOOP directive must have loop control + !!ERROR: DO loop after the KERNELS LOOP directive must have loop control !$acc kernels loop do end do - !ERROR: DO loop after the SERIAL LOOP directive must have loop control + !!ERROR: DO loop after the SERIAL LOOP directive must have loop control !$acc serial loop do end do diff --git a/flang/test/Semantics/OpenACC/acc-combined-loop.f90 b/flang/test/Semantics/OpenACC/acc-combined-loop.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/OpenACC/acc-combined-loop.f90 @@ -0,0 +1,21 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenacc + +program openacc_combined_loop + implicit none + integer :: i + + i = 1 + + !$acc parallel loop + !ERROR: A DO loop must follow the combined construct + i = 1 + + !$acc kernels loop + !ERROR: A DO loop must follow the combined construct + i = 1 + + !$acc serial loop + !ERROR: A DO loop must follow the combined construct + i = 1 + +end diff --git a/flang/test/Semantics/OpenACC/acc-kernels-loop.f90 b/flang/test/Semantics/OpenACC/acc-kernels-loop.f90 --- a/flang/test/Semantics/OpenACC/acc-kernels-loop.f90 +++ b/flang/test/Semantics/OpenACC/acc-kernels-loop.f90 @@ -34,6 +34,18 @@ a(i) = 3.14 end do + !$acc kernels loop + do i = 1, N + a(i) = 3.14 + end do + !$acc end kernels loop + + !$acc kernels loop + do i = 1, N + a(i) = 3.14 + end do + !$acc end kernels loop + !$acc kernels loop num_gangs(8) do i = 1, N a(i) = 3.14 diff --git a/flang/test/Semantics/OpenACC/acc-parallel-loop-validity.f90 b/flang/test/Semantics/OpenACC/acc-parallel-loop-validity.f90 --- a/flang/test/Semantics/OpenACC/acc-parallel-loop-validity.f90 +++ b/flang/test/Semantics/OpenACC/acc-parallel-loop-validity.f90 @@ -17,6 +17,23 @@ real(8), dimension(N) :: a, f, g, h real(8), dimension(N, N) :: aa, bb, cc + !$acc parallel loop + do i = 1, N + a(i) = 3.14 + end do + + !$acc parallel loop + do i = 1, N + a(i) = 3.14 + end do + !$acc end parallel loop + + !$acc parallel loop + do i = 1, N + a(i) = 3.14 + end do + !$acc end parallel + !$acc parallel loop tile(2) do i = 1, N a(i) = 3.14 diff --git a/flang/test/Semantics/OpenACC/acc-serial-loop.f90 b/flang/test/Semantics/OpenACC/acc-serial-loop.f90 --- a/flang/test/Semantics/OpenACC/acc-serial-loop.f90 +++ b/flang/test/Semantics/OpenACC/acc-serial-loop.f90 @@ -94,4 +94,16 @@ !ERROR: Unmatched END PARALLEL LOOP directive !$acc end parallel loop + !$acc serial loop + do i = 1, N + a(i) = 3.14 + end do + !$acc end serial loop + + !$acc serial loop + do i = 1, N + a(i) = 3.14 + end do + !$acc end serial + end program openacc_serial_loop_validity