From ff0220d236dedccb8011873e9b92071fbfa74a0e Mon Sep 17 00:00:00 2001 From: khaki3 <47756807+khaki3@users.noreply.github.com> Date: Wed, 4 Mar 2026 09:41:48 -0800 Subject: [PATCH] [flang][acc] Allow orphaned acc cache directive (#184448) While the spec allows the cache directive at the top of a loop body, the directive has also been utilized at the top of an acc routine. This PR removes the semantic check that rejects the cache directive outside of a loop, allowing orphaned `!$acc cache` similar to CIR. The OpenACC.md deviation document is updated to note this extension. --- flang/docs/OpenACC.md | 1 + flang/lib/Semantics/check-acc-structure.cpp | 10 ---------- flang/lib/Semantics/check-acc-structure.h | 1 - flang/test/Semantics/OpenACC/acc-cache-validity.f90 | 1 - 4 files changed, 1 insertion(+), 12 deletions(-) diff --git a/flang/docs/OpenACC.md b/flang/docs/OpenACC.md index 85e9430a203e..9a166aa9bdde 100644 --- a/flang/docs/OpenACC.md +++ b/flang/docs/OpenACC.md @@ -25,6 +25,7 @@ local: logical expression. * `!$acc routine` directive can be placed at the top level. * `!$acc cache` directive accepts scalar variable. +* `!$acc cache` directive is accepted outside of a loop construct. * The `!$acc declare` directive accepts assumed size array arguments for `deviceptr` and `present` clauses. * The OpenACC specification disallows a variable appearing multiple times in diff --git a/flang/lib/Semantics/check-acc-structure.cpp b/flang/lib/Semantics/check-acc-structure.cpp index fbde2cc366e0..0a41484399b5 100644 --- a/flang/lib/Semantics/check-acc-structure.cpp +++ b/flang/lib/Semantics/check-acc-structure.cpp @@ -422,7 +422,6 @@ 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 &) { @@ -669,11 +668,6 @@ void AccStructureChecker::Enter(const parser::OpenACCCacheConstruct &x) { const auto &verbatim = std::get(x.t); PushContextAndClauseSets(verbatim.source, llvm::acc::Directive::ACCD_cache); SetContextDirectiveSource(verbatim.source); - if (loopNestLevel == 0 && !hasAccRoutineDirective) { - context_.Say(verbatim.source, - "The CACHE directive must be inside a loop or an ACC ROUTINE subprogram"_err_en_US); - } - // Check cache directive array section constraints const auto &objectListWithModifier = std::get(x.t); @@ -1156,22 +1150,18 @@ 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 ffc7ce426388..09399297ca4b 100644 --- a/flang/lib/Semantics/check-acc-structure.h +++ b/flang/lib/Semantics/check-acc-structure.h @@ -115,7 +115,6 @@ private: llvm::SmallDenseMap 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 ab79c1b4061a..de66043de1ec 100644 --- a/flang/test/Semantics/OpenACC/acc-cache-validity.f90 +++ b/flang/test/Semantics/OpenACC/acc-cache-validity.f90 @@ -52,7 +52,6 @@ program openacc_cache_validity end do - !ERROR: The CACHE directive must be inside a loop or an ACC ROUTINE subprogram !$acc cache(a) call routine_with_cache()