[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:53:23 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-semantics

Author: None (khaki3)

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/184213.diff


3 Files Affected:

- (modified) flang/lib/Semantics/check-acc-structure.cpp (+6-1) 
- (modified) flang/lib/Semantics/check-acc-structure.h (+1) 
- (modified) flang/test/Semantics/OpenACC/acc-cache-validity.f90 (+15) 


``````````diff
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

``````````

</details>


https://github.com/llvm/llvm-project/pull/184213


More information about the flang-commits mailing list