[flang][openacc] Add check for acc cache directive (#65807)

OpenACC 3.3 - 2.10 The cache directive may appear at the top of (inside
of) a loop.

This patch adds a semantic check to ensure the cache directive is inside
a loop.
This commit is contained in:
Valentin Clement (バレンタイン クレメン)
2023-09-08 14:50:47 -07:00
committed by GitHub
parent 210e7b3ca7
commit db20592ffe
3 changed files with 22 additions and 0 deletions

View File

@@ -335,6 +335,10 @@ 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) {
context_.Say(verbatim.source,
"The CACHE directive must be inside a loop"_err_en_US);
}
}
void AccStructureChecker::Leave(const parser::OpenACCCacheConstruct &x) {
dirContext_.pop_back();
@@ -655,6 +659,14 @@ void AccStructureChecker::Enter(const parser::SeparateModuleSubprogram &) {
declareSymbols.clear();
}
void AccStructureChecker::Enter(const parser::DoConstruct &) {
++loopNestLevel;
}
void AccStructureChecker::Leave(const parser::DoConstruct &) {
--loopNestLevel;
}
llvm::StringRef AccStructureChecker::getDirectiveName(
llvm::acc::Directive directive) {
return llvm::acc::getOpenACCDirectiveName(directive);

View File

@@ -71,6 +71,8 @@ public:
void Enter(const parser::SubroutineSubprogram &);
void Enter(const parser::FunctionSubprogram &);
void Enter(const parser::SeparateModuleSubprogram &);
void Enter(const parser::DoConstruct &);
void Leave(const parser::DoConstruct &);
#define GEN_FLANG_CLAUSE_CHECK_ENTER
#include "llvm/Frontend/OpenACC/ACC.inc"
@@ -88,6 +90,7 @@ private:
llvm::StringRef getDirectiveName(llvm::acc::Directive directive) override;
llvm::SmallDenseSet<Symbol *> declareSymbols;
unsigned loopNestLevel = 0;
};
} // namespace Fortran::semantics

View File

@@ -19,6 +19,8 @@ program openacc_cache_validity
type(atype), dimension(10) :: ta
real(8), dimension(N) :: a
do i = 1, N
!$acc cache(a(i))
!$acc cache(a(1:2,3:4))
!$acc cache(a)
@@ -40,4 +42,9 @@ program openacc_cache_validity
!ERROR: Only array element or subarray are allowed in CACHE directive
!$acc cache(/i/)
end do
!ERROR: The CACHE directive must be inside a loop
!$acc cache(a)
end program openacc_cache_validity