[flang-commits] [flang] [flang] Allow acc cache directive inside acc routine (PR #184213)
via flang-commits
flang-commits at lists.llvm.org
Mon Mar 2 11:52:53 PST 2026
https://github.com/khaki3 created https://github.com/llvm/llvm-project/pull/184213
While the spec allows the cache directive "at the top of (inside of) a loop", the directive has also been utilized at the top of an acc routine. This PR adds support for that.
>From b3caaa771b215c95c040eddf4ae4d26a0cfd8078 Mon Sep 17 00:00:00 2001
From: Kazuaki Matsumura <kmatsumura at nvidia.com>
Date: Mon, 2 Mar 2026 11:44:19 -0800
Subject: [PATCH] [flang] Allow acc cache directive inside acc routine
Made-with: Cursor
---
flang/lib/Semantics/check-acc-structure.cpp | 7 ++++++-
flang/lib/Semantics/check-acc-structure.h | 1 +
.../test/Semantics/OpenACC/acc-cache-validity.f90 | 15 +++++++++++++++
3 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/flang/lib/Semantics/check-acc-structure.cpp b/flang/lib/Semantics/check-acc-structure.cpp
index 24fdc7c048e5d..7a40b4f914c03 100644
--- a/flang/lib/Semantics/check-acc-structure.cpp
+++ b/flang/lib/Semantics/check-acc-structure.cpp
@@ -422,6 +422,7 @@ void AccStructureChecker::Enter(const parser::OpenACCRoutineConstruct &x) {
"part of a subroutine or function definition, or within an interface "
"body for a subroutine or function in an interface block"_err_en_US);
}
+ hasAccRoutineDirective = true;
}
}
void AccStructureChecker::Leave(const parser::OpenACCRoutineConstruct &) {
@@ -668,7 +669,7 @@ void AccStructureChecker::Enter(const parser::OpenACCCacheConstruct &x) {
const auto &verbatim = std::get<parser::Verbatim>(x.t);
PushContextAndClauseSets(verbatim.source, llvm::acc::Directive::ACCD_cache);
SetContextDirectiveSource(verbatim.source);
- if (loopNestLevel == 0) {
+ if (loopNestLevel == 0 && !hasAccRoutineDirective) {
context_.Say(
verbatim.source, "The CACHE directive must be inside a loop"_err_en_US);
}
@@ -1155,18 +1156,22 @@ void AccStructureChecker::Enter(const parser::OpenACCEndConstruct &x) {
void AccStructureChecker::Enter(const parser::Module &) {
declareSymbols.clear();
+ hasAccRoutineDirective = false;
}
void AccStructureChecker::Enter(const parser::FunctionSubprogram &x) {
declareSymbols.clear();
+ hasAccRoutineDirective = false;
}
void AccStructureChecker::Enter(const parser::SubroutineSubprogram &) {
declareSymbols.clear();
+ hasAccRoutineDirective = false;
}
void AccStructureChecker::Enter(const parser::SeparateModuleSubprogram &) {
declareSymbols.clear();
+ hasAccRoutineDirective = false;
}
void AccStructureChecker::Enter(const parser::DoConstruct &) {
diff --git a/flang/lib/Semantics/check-acc-structure.h b/flang/lib/Semantics/check-acc-structure.h
index 09399297ca4be..ffc7ce4263885 100644
--- a/flang/lib/Semantics/check-acc-structure.h
+++ b/flang/lib/Semantics/check-acc-structure.h
@@ -115,6 +115,7 @@ class AccStructureChecker
llvm::SmallDenseMap<Symbol *, llvm::acc::Clause> declareSymbols;
unsigned loopNestLevel = 0;
+ bool hasAccRoutineDirective = false;
};
} // namespace Fortran::semantics
diff --git a/flang/test/Semantics/OpenACC/acc-cache-validity.f90 b/flang/test/Semantics/OpenACC/acc-cache-validity.f90
index cef8fc041ae32..f0269b2460c90 100644
--- a/flang/test/Semantics/OpenACC/acc-cache-validity.f90
+++ b/flang/test/Semantics/OpenACC/acc-cache-validity.f90
@@ -55,4 +55,19 @@ program openacc_cache_validity
!ERROR: The CACHE directive must be inside a loop
!$acc cache(a)
+ call routine_with_cache()
+
+contains
+
+ subroutine routine_with_cache()
+ real(8), dimension(N) :: local_arr
+ integer :: j
+ !$acc routine vector
+ !$acc cache(local_arr)
+ !$acc loop
+ do j = 1, N
+ local_arr(j) = a(j)
+ end do
+ end subroutine
+
end program openacc_cache_validity
More information about the flang-commits
mailing list