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

Valentin Clement バレンタイン クレメン via flang-commits flang-commits at lists.llvm.org
Fri Sep 8 14:15:44 PDT 2023


https://github.com/clementval created https://github.com/llvm/llvm-project/pull/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.

>From de7bcbf7719ef70686ba6374f4f2a76942e28d6e Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Fri, 8 Sep 2023 14:14:42 -0700
Subject: [PATCH] [flang][openacc] Add check for acc cache directive

---
 flang/lib/Semantics/check-acc-structure.cpp         | 12 ++++++++++++
 flang/lib/Semantics/check-acc-structure.h           |  3 +++
 flang/test/Semantics/OpenACC/acc-cache-validity.f90 |  7 +++++++
 3 files changed, 22 insertions(+)

diff --git a/flang/lib/Semantics/check-acc-structure.cpp b/flang/lib/Semantics/check-acc-structure.cpp
index 692a7a408947aa7..4ae034736a40b09 100644
--- a/flang/lib/Semantics/check-acc-structure.cpp
+++ b/flang/lib/Semantics/check-acc-structure.cpp
@@ -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);
diff --git a/flang/lib/Semantics/check-acc-structure.h b/flang/lib/Semantics/check-acc-structure.h
index 8c0d7150dd47b0b..6d05acba92cb268 100644
--- a/flang/lib/Semantics/check-acc-structure.h
+++ b/flang/lib/Semantics/check-acc-structure.h
@@ -71,6 +71,8 @@ class AccStructureChecker
   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 @@ class AccStructureChecker
   llvm::StringRef getDirectiveName(llvm::acc::Directive directive) override;
 
   llvm::SmallDenseSet<Symbol *> declareSymbols;
+  unsigned loopNestLevel = 0;
 };
 
 } // namespace Fortran::semantics
diff --git a/flang/test/Semantics/OpenACC/acc-cache-validity.f90 b/flang/test/Semantics/OpenACC/acc-cache-validity.f90
index 9afdd6def21fdef..9eb12b9e2b7e4d4 100644
--- a/flang/test/Semantics/OpenACC/acc-cache-validity.f90
+++ b/flang/test/Semantics/OpenACC/acc-cache-validity.f90
@@ -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



More information about the flang-commits mailing list