[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.
This commit is contained in:
khaki3 2026-03-04 09:41:48 -08:00 committed by GitHub
parent 937bf9cef6
commit ff0220d236
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 1 additions and 12 deletions

View File

@ -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

View File

@ -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<parser::Verbatim>(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<parser::AccObjectListWithModifier>(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 &) {

View File

@ -115,7 +115,6 @@ private:
llvm::SmallDenseMap<Symbol *, llvm::acc::Clause> declareSymbols;
unsigned loopNestLevel = 0;
bool hasAccRoutineDirective = false;
};
} // namespace Fortran::semantics

View File

@ -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()