diff --git a/flang/lib/Semantics/check-acc-structure.cpp b/flang/lib/Semantics/check-acc-structure.cpp index 6cb7e5e9e6e25..3cd6d6ba7689a 100644 --- a/flang/lib/Semantics/check-acc-structure.cpp +++ b/flang/lib/Semantics/check-acc-structure.cpp @@ -136,10 +136,10 @@ void AccStructureChecker::CheckNotInComputeConstruct() { } } -bool AccStructureChecker::IsInsideParallelConstruct() const { +bool AccStructureChecker::IsInsideKernelsConstruct() const { if (auto directive = getParentComputeConstruct()) - if (*directive == llvm::acc::ACCD_parallel || - *directive == llvm::acc::ACCD_parallel_loop) + if (*directive == llvm::acc::ACCD_kernels || + *directive == llvm::acc::ACCD_kernels_loop) return true; return false; } @@ -293,7 +293,10 @@ void AccStructureChecker::CheckNotInSameOrSubLevelLoopConstruct() { bool invalid{false}; if (parentClause == llvm::acc::Clause::ACCC_gang && cl == llvm::acc::Clause::ACCC_gang) { - if (IsInsideParallelConstruct()) { + if (IsInsideKernelsConstruct()) { + context_.Say(GetContext().clauseSource, + "Nested GANG loops are not allowed in the region of a KERNELS construct"_err_en_US); + } else { auto parentDim = getGangDimensionSize(parent); auto currentDim = getGangDimensionSize(GetContext()); std::int64_t parentDimNum = 1, currentDimNum = 1; @@ -317,8 +320,6 @@ void AccStructureChecker::CheckNotInSameOrSubLevelLoopConstruct() { parentDimStr); continue; } - } else { - invalid = true; } } else if (parentClause == llvm::acc::Clause::ACCC_worker && (cl == llvm::acc::Clause::ACCC_gang || diff --git a/flang/lib/Semantics/check-acc-structure.h b/flang/lib/Semantics/check-acc-structure.h index 711d0326349a4..09399297ca4be 100644 --- a/flang/lib/Semantics/check-acc-structure.h +++ b/flang/lib/Semantics/check-acc-structure.h @@ -101,7 +101,7 @@ class AccStructureChecker bool IsLoopConstruct(llvm::acc::Directive directive) const; std::optional getParentComputeConstruct() const; bool IsInsideComputeConstruct() const; - bool IsInsideParallelConstruct() const; + bool IsInsideKernelsConstruct() const; void CheckNotInComputeConstruct(); std::optional getGangDimensionSize( DirectiveContext &dirContext); diff --git a/flang/test/Semantics/OpenACC/acc-loop.f90 b/flang/test/Semantics/OpenACC/acc-loop.f90 index 77c427e0a85ae..635dbb04cd666 100644 --- a/flang/test/Semantics/OpenACC/acc-loop.f90 +++ b/flang/test/Semantics/OpenACC/acc-loop.f90 @@ -340,10 +340,10 @@ program openacc_loop_validity !$acc kernels loop gang(dim:3) do i = 1, n - !ERROR: GANG clause is not allowed in the region of a loop with the GANG clause + !ERROR: Nested GANG loops are not allowed in the region of a KERNELS construct !$acc loop gang(dim:2) do j = 1, n - !ERROR: GANG clause is not allowed in the region of a loop with the GANG clause + !ERROR: Nested GANG loops are not allowed in the region of a KERNELS construct !$acc loop gang(dim:1) worker vector do k = 1, i end do @@ -447,4 +447,35 @@ program openacc_loop_validity END DO END DO +contains + + subroutine sub1() + !$acc routine gang(dim:2) + implicit none + integer, parameter :: N = 256 + integer :: i, j + + !$acc loop gang(dim:2) + DO j = 1, N + !$acc loop gang(dim:1) vector + DO i = 1, N + END DO + END DO + end subroutine sub1 + + subroutine sub2() + !$acc routine gang(dim:2) + implicit none + integer, parameter :: N = 256 + integer :: i, j + + !$acc loop gang(dim:2) + DO j = 1, N + !ERROR: GANG(dim:2) clause is not allowed in the region of a loop with the GANG(dim:2) clause + !$acc loop gang(dim:2) vector + DO i = 1, N + END DO + END DO + end subroutine sub2 + end program openacc_loop_validity