diff --git a/flang/lib/Semantics/check-acc-structure.cpp b/flang/lib/Semantics/check-acc-structure.cpp index 932d5776a04680c..4a5798a8a531a4c 100644 --- a/flang/lib/Semantics/check-acc-structure.cpp +++ b/flang/lib/Semantics/check-acc-structure.cpp @@ -225,7 +225,8 @@ void AccStructureChecker::Leave(const parser::OpenACCCombinedConstruct &x) { case llvm::acc::Directive::ACCD_serial_loop: // Restriction - line 1004-1005 CheckOnlyAllowedAfter(llvm::acc::Clause::ACCC_device_type, - computeConstructOnlyAllowedAfterDeviceTypeClauses); + computeConstructOnlyAllowedAfterDeviceTypeClauses | + loopOnlyAllowedAfterDeviceTypeClauses); if (doCons) { const parser::Block &block{std::get(doCons->t)}; CheckNoBranching(block, GetContext().directive, beginBlockDir.source); @@ -388,11 +389,8 @@ CHECK_SIMPLE_CLAUSE(Nohost, ACCC_nohost) CHECK_SIMPLE_CLAUSE(Private, ACCC_private) CHECK_SIMPLE_CLAUSE(Read, ACCC_read) CHECK_SIMPLE_CLAUSE(Seq, ACCC_seq) -CHECK_SIMPLE_CLAUSE(Tile, ACCC_tile) CHECK_SIMPLE_CLAUSE(UseDevice, ACCC_use_device) -CHECK_SIMPLE_CLAUSE(Vector, ACCC_vector) CHECK_SIMPLE_CLAUSE(Wait, ACCC_wait) -CHECK_SIMPLE_CLAUSE(Worker, ACCC_worker) CHECK_SIMPLE_CLAUSE(Write, ACCC_write) CHECK_SIMPLE_CLAUSE(Unknown, ACCC_unknown) @@ -536,8 +534,28 @@ void AccStructureChecker::Enter(const parser::AccClause::DeviceType &d) { } } +void AccStructureChecker::Enter(const parser::AccClause::Vector &g) { + CheckAllowed(llvm::acc::Clause::ACCC_vector); + CheckAllowedOncePerGroup( + llvm::acc::Clause::ACCC_vector, llvm::acc::Clause::ACCC_device_type); +} + +void AccStructureChecker::Enter(const parser::AccClause::Worker &g) { + CheckAllowed(llvm::acc::Clause::ACCC_worker); + CheckAllowedOncePerGroup( + llvm::acc::Clause::ACCC_worker, llvm::acc::Clause::ACCC_device_type); +} + +void AccStructureChecker::Enter(const parser::AccClause::Tile &g) { + CheckAllowed(llvm::acc::Clause::ACCC_tile); + CheckAllowedOncePerGroup( + llvm::acc::Clause::ACCC_tile, llvm::acc::Clause::ACCC_device_type); +} + void AccStructureChecker::Enter(const parser::AccClause::Gang &g) { CheckAllowed(llvm::acc::Clause::ACCC_gang); + CheckAllowedOncePerGroup( + llvm::acc::Clause::ACCC_gang, llvm::acc::Clause::ACCC_device_type); if (g.v) { bool hasNum = false; @@ -665,6 +683,8 @@ void AccStructureChecker::Enter(const parser::AccClause::Self &x) { void AccStructureChecker::Enter(const parser::AccClause::Collapse &x) { CheckAllowed(llvm::acc::Clause::ACCC_collapse); + CheckAllowedOncePerGroup( + llvm::acc::Clause::ACCC_collapse, llvm::acc::Clause::ACCC_device_type); const parser::AccCollapseArg &accCollapseArg = x.v; const auto &collapseValue{ std::get(accCollapseArg.t)}; diff --git a/flang/test/Semantics/OpenACC/acc-loop.f90 b/flang/test/Semantics/OpenACC/acc-loop.f90 index f5d1e501a2b329d..fde836852c51ed5 100644 --- a/flang/test/Semantics/OpenACC/acc-loop.f90 +++ b/flang/test/Semantics/OpenACC/acc-loop.f90 @@ -63,7 +63,7 @@ program openacc_loop_validity !$acc end parallel !$acc parallel - !ERROR: At most one VECTOR clause can appear on the LOOP directive + !ERROR: At most one VECTOR clause can appear on the LOOP directive or in group separated by the DEVICE_TYPE clause !$acc loop vector vector(128) do i = 1, N a(i) = 3.14 @@ -99,7 +99,7 @@ program openacc_loop_validity !$acc end parallel !$acc parallel - !ERROR: At most one WORKER clause can appear on the LOOP directive + !ERROR: At most one WORKER clause can appear on the LOOP directive or in group separated by the DEVICE_TYPE clause !$acc loop worker worker(10) do i = 1, N a(i) = 3.14 @@ -135,13 +135,29 @@ program openacc_loop_validity !$acc end parallel !$acc parallel - !ERROR: At most one GANG clause can appear on the LOOP directive + !ERROR: At most one GANG clause can appear on the LOOP directive or in group separated by the DEVICE_TYPE clause !$acc loop gang gang(gang_size) do i = 1, N a(i) = 3.14 end do !$acc end parallel + !$acc loop gang device_type(default) gang(gang_size) + do i = 1, N + a(i) = 3.14 + end do + + !ERROR: At most one GANG clause can appear on the PARALLEL LOOP directive or in group separated by the DEVICE_TYPE clause + !$acc parallel loop gang gang(gang_size) + do i = 1, N + a(i) = 3.14 + end do + + !$acc parallel loop gang device_type(default) gang(gang_size) + do i = 1, N + a(i) = 3.14 + end do + !$acc parallel !$acc loop gang(gang_size) do i = 1, N @@ -283,4 +299,22 @@ program openacc_loop_validity end do !$acc end parallel + !$acc loop gang device_type(nvidia) gang(num: 8) + DO i = 1, n + END DO + + !$acc loop vector device_type(default) vector(16) + DO i = 1, n + END DO + + !$acc loop worker device_type(*) worker(8) + DO i = 1, n + END DO + + !$acc loop device_type(multicore) collapse(2) + DO i = 1, n + DO j = 1, n + END DO + END DO + end program openacc_loop_validity diff --git a/llvm/include/llvm/Frontend/OpenACC/ACC.td b/llvm/include/llvm/Frontend/OpenACC/ACC.td index 013d18e160de461..0dbd934d83f0641 100644 --- a/llvm/include/llvm/Frontend/OpenACC/ACC.td +++ b/llvm/include/llvm/Frontend/OpenACC/ACC.td @@ -391,9 +391,7 @@ def ACC_Loop : Directive<"loop"> { let allowedClauses = [ VersionedClause, VersionedClause, - VersionedClause - ]; - let allowedOnceClauses = [ + VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -421,15 +419,17 @@ def ACC_Init : Directive<"init"> { // 2.15.1 def ACC_Routine : Directive<"routine"> { - let allowedOnceClauses = [ + let allowedClauses = [ VersionedClause, VersionedClause, - VersionedClause, VersionedClause, VersionedClause, VersionedClause, VersionedClause ]; + let allowedOnceClauses = [ + VersionedClause + ]; } // 2.14.3 @@ -532,32 +532,32 @@ def ACC_HostData : Directive<"host_data"> { // 2.11 def ACC_KernelsLoop : Directive<"kernels loop"> { let allowedClauses = [ + VersionedClause, + VersionedClause, VersionedClause, VersionedClause, VersionedClause, VersionedClause, + VersionedClause, VersionedClause, + VersionedClause, VersionedClause, + VersionedClause, + VersionedClause, VersionedClause, VersionedClause, VersionedClause, - VersionedClause, - VersionedClause, - VersionedClause + VersionedClause, + VersionedClause, + VersionedClause, + VersionedClause, + VersionedClause ]; let allowedOnceClauses = [ VersionedClause, - VersionedClause, VersionedClause, - VersionedClause, VersionedClause, - VersionedClause, - VersionedClause, - VersionedClause, - VersionedClause, - VersionedClause, - VersionedClause, - VersionedClause + VersionedClause ]; let allowedExclusiveClauses = [ VersionedClause, @@ -570,6 +570,7 @@ def ACC_KernelsLoop : Directive<"kernels loop"> { def ACC_ParallelLoop : Directive<"parallel loop"> { let allowedClauses = [ VersionedClause, + VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -577,25 +578,24 @@ def ACC_ParallelLoop : Directive<"parallel loop"> { VersionedClause, VersionedClause, VersionedClause, + VersionedClause, VersionedClause, + VersionedClause, + VersionedClause, VersionedClause, VersionedClause, VersionedClause, VersionedClause, - VersionedClause + VersionedClause, + VersionedClause, + VersionedClause, + VersionedClause ]; let allowedOnceClauses = [ VersionedClause, - VersionedClause, VersionedClause, - VersionedClause, VersionedClause, - VersionedClause, - VersionedClause, - VersionedClause, - VersionedClause, - VersionedClause, - VersionedClause + VersionedClause ]; let allowedExclusiveClauses = [ VersionedClause, @@ -608,6 +608,7 @@ def ACC_ParallelLoop : Directive<"parallel loop"> { def ACC_SerialLoop : Directive<"serial loop"> { let allowedClauses = [ VersionedClause, + VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -615,22 +616,21 @@ def ACC_SerialLoop : Directive<"serial loop"> { VersionedClause, VersionedClause, VersionedClause, + VersionedClause, VersionedClause, VersionedClause, VersionedClause, VersionedClause, - VersionedClause + VersionedClause, + VersionedClause, + VersionedClause, + VersionedClause ]; let allowedOnceClauses = [ VersionedClause, - VersionedClause, VersionedClause, - VersionedClause, VersionedClause, - VersionedClause, - VersionedClause, - VersionedClause, - VersionedClause + VersionedClause ]; let allowedExclusiveClauses = [ VersionedClause,