From ce6bcb71669681c26c8c312ac4a1d0ffc71d6910 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsumura Date: Mon, 15 Sep 2025 10:25:08 -0700 Subject: [PATCH 1/2] Allow nested gang clauses in acc routines --- flang/lib/Semantics/check-acc-structure.cpp | 8 +++--- flang/lib/Semantics/check-acc-structure.h | 2 +- flang/test/Semantics/OpenACC/acc-loop.f90 | 31 +++++++++++++++++++++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/flang/lib/Semantics/check-acc-structure.cpp b/flang/lib/Semantics/check-acc-structure.cpp index 6cb7e5e9e6e25..bcb485d4e0f47 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,7 @@ void AccStructureChecker::CheckNotInSameOrSubLevelLoopConstruct() { bool invalid{false}; if (parentClause == llvm::acc::Clause::ACCC_gang && cl == llvm::acc::Clause::ACCC_gang) { - if (IsInsideParallelConstruct()) { + if (!IsInsideKernelsConstruct()) { auto parentDim = getGangDimensionSize(parent); auto currentDim = getGangDimensionSize(GetContext()); std::int64_t parentDimNum = 1, currentDimNum = 1; 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..d3777f48430e5 100644 --- a/flang/test/Semantics/OpenACC/acc-loop.f90 +++ b/flang/test/Semantics/OpenACC/acc-loop.f90 @@ -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 From 552e99faa483b7e8e125880470d6bd0cd2f10173 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsumura Date: Tue, 16 Sep 2025 04:54:22 -0700 Subject: [PATCH 2/2] Reverse logic; Update the error message for the nested gang loops --- flang/lib/Semantics/check-acc-structure.cpp | 7 ++++--- flang/test/Semantics/OpenACC/acc-loop.f90 | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/flang/lib/Semantics/check-acc-structure.cpp b/flang/lib/Semantics/check-acc-structure.cpp index bcb485d4e0f47..3cd6d6ba7689a 100644 --- a/flang/lib/Semantics/check-acc-structure.cpp +++ b/flang/lib/Semantics/check-acc-structure.cpp @@ -293,7 +293,10 @@ void AccStructureChecker::CheckNotInSameOrSubLevelLoopConstruct() { bool invalid{false}; if (parentClause == llvm::acc::Clause::ACCC_gang && cl == llvm::acc::Clause::ACCC_gang) { - if (!IsInsideKernelsConstruct()) { + 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/test/Semantics/OpenACC/acc-loop.f90 b/flang/test/Semantics/OpenACC/acc-loop.f90 index d3777f48430e5..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