diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index eeb438991feee..0c2a5de3b71d2 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -5244,21 +5244,23 @@ EMPTY_CLASS(AccEndAtomic); // ACC ATOMIC READ struct AccAtomicRead { TUPLE_CLASS_BOILERPLATE(AccAtomicRead); - std::tuple, std::optional> + std::tuple, + std::optional> t; }; // ACC ATOMIC WRITE struct AccAtomicWrite { TUPLE_CLASS_BOILERPLATE(AccAtomicWrite); - std::tuple, std::optional> + std::tuple, + std::optional> t; }; // ACC ATOMIC UPDATE struct AccAtomicUpdate { TUPLE_CLASS_BOILERPLATE(AccAtomicUpdate); - std::tuple, Statement, + std::tuple, AccClauseList, Statement, std::optional> t; }; @@ -5268,7 +5270,7 @@ struct AccAtomicCapture { TUPLE_CLASS_BOILERPLATE(AccAtomicCapture); WRAPPER_CLASS(Stmt1, Statement); WRAPPER_CLASS(Stmt2, Statement); - std::tuple t; + std::tuple t; }; struct OpenACCAtomicConstruct { diff --git a/flang/lib/Parser/openacc-parsers.cpp b/flang/lib/Parser/openacc-parsers.cpp index fb731ee52cbba..072eba99826a1 100644 --- a/flang/lib/Parser/openacc-parsers.cpp +++ b/flang/lib/Parser/openacc-parsers.cpp @@ -187,22 +187,25 @@ TYPE_PARSER(construct( // 2.12 Atomic constructs TYPE_PARSER(construct(startAccLine >> "END ATOMIC"_tok)) -TYPE_PARSER("ATOMIC" >> - construct(verbatim("READ"_tok) / endAccLine, - statement(assignmentStmt), maybe(Parser{} / endAccLine))) +TYPE_PARSER("ATOMIC" >> construct(verbatim("READ"_tok), + Parser{} / endAccLine, + statement(assignmentStmt), + maybe(Parser{} / endAccLine))) -TYPE_PARSER("ATOMIC" >> - construct(verbatim("WRITE"_tok) / endAccLine, - statement(assignmentStmt), maybe(Parser{} / endAccLine))) +TYPE_PARSER("ATOMIC" >> construct(verbatim("WRITE"_tok), + Parser{} / endAccLine, + statement(assignmentStmt), + maybe(Parser{} / endAccLine))) TYPE_PARSER("ATOMIC" >> - construct(maybe(verbatim("UPDATE"_tok)) / endAccLine, - statement(assignmentStmt), maybe(Parser{} / endAccLine))) + construct(maybe(verbatim("UPDATE"_tok)), + Parser{} / endAccLine, statement(assignmentStmt), + maybe(Parser{} / endAccLine))) TYPE_PARSER("ATOMIC" >> - construct(verbatim("CAPTURE"_tok) / endAccLine, - statement(assignmentStmt), statement(assignmentStmt), - Parser{} / endAccLine)) + construct(verbatim("CAPTURE"_tok), + Parser{} / endAccLine, statement(assignmentStmt), + statement(assignmentStmt), Parser{} / endAccLine)) TYPE_PARSER( sourced(construct(Parser{})) || diff --git a/flang/test/Semantics/OpenACC/acc-atomic-validity.f90 b/flang/test/Semantics/OpenACC/acc-atomic-validity.f90 index ba68031b0f18b..07fb864695737 100644 --- a/flang/test/Semantics/OpenACC/acc-atomic-validity.f90 +++ b/flang/test/Semantics/OpenACC/acc-atomic-validity.f90 @@ -10,6 +10,7 @@ program openacc_atomic_validity integer :: i integer, parameter :: N = 256 integer, dimension(N) :: c + logical :: l !$acc parallel @@ -23,27 +24,58 @@ program openacc_atomic_validity !$acc atomic write c(i) = 10 + !$acc atomic write if(l) + c(i) = 10 + !$acc atomic write c(i) = 10 !$acc end atomic + !$acc atomic write if(.true.) + c(i) = 10 + !$acc end atomic + !$acc atomic read i = c(i) + + !$acc atomic read if(.true.) + i = c(i) !$acc atomic read i = c(i) !$acc end atomic + !$acc atomic read if(l) + i = c(i) + !$acc end atomic + + !ERROR: FINALIZE clause is not allowed on the ATOMIC READ FINALIZE IF(L) + !$acc atomic read finalize if(l) + i = c(i) + !$acc end atomic + !$acc atomic capture c(i) = i i = i + 1 !$acc end atomic + !$acc atomic capture if(l .EQV. .false.) + c(i) = i + i = i + 1 + !$acc end atomic + !$acc atomic update !ERROR: RHS of atomic update statement must be scalar !ERROR: LHS of atomic update statement must be scalar c = c + 1 + !$acc atomic update if(i == 0) + c(i) = c(i) + 1 + + !ERROR: At most one IF clause can appear on the ATOMIC UPDATE IF(I == 0) IF(.TRUE.) + !$acc atomic update if(i == 0) if(.true.) + c(i) = c(i) + 1 + !$acc end parallel end program openacc_atomic_validity diff --git a/llvm/include/llvm/Frontend/OpenACC/ACC.td b/llvm/include/llvm/Frontend/OpenACC/ACC.td index 8729d4505205b..c77988b21c1e3 100644 --- a/llvm/include/llvm/Frontend/OpenACC/ACC.td +++ b/llvm/include/llvm/Frontend/OpenACC/ACC.td @@ -270,6 +270,7 @@ def ACCC_Unknown : Clause<"unknown"> { // 2.12 def ACC_Atomic : Directive<"atomic"> { + let allowedOnceClauses = [VersionedClause]; let association = AS_Block; let category = CA_Executable; }