[flang][OpenMP] Check for occurrence of multiple list items in nontemporal clause...
authorArnamoy Bhattacharyya <arnamoy.bhattacharyya@huawei.com>
Mon, 30 May 2022 14:10:54 +0000 (10:10 -0400)
committerArnamoy Bhattacharyya <arnamoy.bhattacharyya@huawei.com>
Mon, 30 May 2022 14:59:23 +0000 (10:59 -0400)
This patch implements the following semantic check:

A list-item cannot appear in more than one nontemporal clause.

Reviewed By: kiranchandramohan, shraiysh

Differential Revision: https://reviews.llvm.org/D110270

flang/lib/Semantics/check-omp-structure.cpp
flang/lib/Semantics/check-omp-structure.h
flang/test/Semantics/omp-simd-nontemporal.f90 [new file with mode: 0644]

index 83acaba..38ca2e1 100644 (file)
@@ -170,6 +170,42 @@ bool OmpStructureChecker::IsCloselyNestedRegion(const OmpDirectiveSet &set) {
   return false;
 }
 
+void OmpStructureChecker::CheckMultListItems() {
+  semantics::UnorderedSymbolSet listVars;
+  auto checkMultipleOcurrence = [&](const std::list<parser::Name> &nameList,
+                                    const parser::CharBlock &item,
+                                    const std::string &clauseName) {
+    for (auto const &var : nameList) {
+      if (llvm::is_contained(listVars, *(var.symbol))) {
+        context_.Say(item,
+            "List item '%s' present at multiple %s clauses"_err_en_US,
+            var.ToString(), clauseName);
+      }
+      listVars.insert(*(var.symbol));
+    }
+  };
+
+  // Aligned clause
+  auto alignedClauses{FindClauses(llvm::omp::Clause::OMPC_aligned)};
+  for (auto itr = alignedClauses.first; itr != alignedClauses.second; ++itr) {
+    const auto &alignedClause{
+        std::get<parser::OmpClause::Aligned>(itr->second->u)};
+    const auto &alignedNameList{
+        std::get<std::list<parser::Name>>(alignedClause.v.t)};
+    checkMultipleOcurrence(alignedNameList, itr->second->source, "ALIGNED");
+  }
+
+  // Nontemporal clause
+  auto nonTemporalClauses{FindClauses(llvm::omp::Clause::OMPC_nontemporal)};
+  for (auto itr = nonTemporalClauses.first; itr != nonTemporalClauses.second;
+       ++itr) {
+    const auto &nontempClause{
+        std::get<parser::OmpClause::Nontemporal>(itr->second->u)};
+    const auto &nontempNameList{nontempClause.v};
+    checkMultipleOcurrence(nontempNameList, itr->second->source, "NONTEMPORAL");
+  }
+}
+
 bool OmpStructureChecker::HasInvalidWorksharingNesting(
     const parser::CharBlock &source, const OmpDirectiveSet &set) {
   // set contains all the invalid closely nested directives
@@ -1660,24 +1696,9 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
         }
       }
     }
-    // A list-item cannot appear in more than one aligned clause
-    semantics::UnorderedSymbolSet alignedVars;
-    auto clauseAll = FindClauses(llvm::omp::Clause::OMPC_aligned);
-    for (auto itr = clauseAll.first; itr != clauseAll.second; ++itr) {
-      const auto &alignedClause{
-          std::get<parser::OmpClause::Aligned>(itr->second->u)};
-      const auto &alignedNameList{
-          std::get<std::list<parser::Name>>(alignedClause.v.t)};
-      for (auto const &var : alignedNameList) {
-        if (alignedVars.count(*(var.symbol)) == 1) {
-          context_.Say(itr->second->source,
-              "List item '%s' present at multiple ALIGNED clauses"_err_en_US,
-              var.ToString());
-          break;
-        }
-        alignedVars.insert(*(var.symbol));
-      }
-    }
+    // Sema checks related to presence of multiple list items within the same
+    // clause
+    CheckMultListItems();
   } // SIMD
 
   // 2.7.3 Single Construct Restriction
index 6352b80..ccf3b06 100644 (file)
@@ -191,6 +191,7 @@ public:
   }
 
 private:
+  void CheckMultListItems();
   bool HasInvalidWorksharingNesting(
       const parser::CharBlock &, const OmpDirectiveSet &);
   bool IsCloselyNestedRegion(const OmpDirectiveSet &set);
diff --git a/flang/test/Semantics/omp-simd-nontemporal.f90 b/flang/test/Semantics/omp-simd-nontemporal.f90
new file mode 100644 (file)
index 0000000..a6b7123
--- /dev/null
@@ -0,0 +1,63 @@
+! RUN: %python %S/test_errors.py %s %flang -fopenmp
+
+! OpenMP Version 4.5
+! 2.8.1 simd Construct
+! Semantic error for correct test case
+
+program omp_simd
+  integer i, j, k
+  integer, allocatable :: a(:), b(:)
+
+  allocate(a(10))
+  allocate(b(10))
+
+  !ERROR: List item 'a' present at multiple NONTEMPORAL clauses
+  !$omp simd nontemporal(a, a)
+  do i = 1, 10
+    a(i) = i
+  end do
+  !$omp end simd
+
+  !ERROR: List item 'a' present at multiple NONTEMPORAL clauses
+  !ERROR: List item 'b' present at multiple NONTEMPORAL clauses
+  !$omp simd nontemporal(a,a) nontemporal(b) nontemporal(b)
+  do i = 1, 10
+    a(i) = i
+    b(i) = i
+  end do
+  !$omp end simd
+
+  !ERROR: List item 'a' present at multiple NONTEMPORAL clauses
+  !$omp simd nontemporal(a) nontemporal(a)
+  do i = 1, 10
+    a(i) = i
+  end do
+  !$omp end simd
+
+  !$omp simd nontemporal(a) nontemporal(b)
+  do i = 1, 10
+    a(i) = i
+    b(i) = i
+  end do
+  !$omp end simd
+
+  !ERROR: List item 'a' present at multiple NONTEMPORAL clauses
+  !$omp simd nontemporal(a) private(a) nontemporal(a)
+  do i = 1, 10
+    a(i) = i
+    b(i) = i
+  end do
+  !$omp end simd
+
+  !ERROR: List item 'a' present at multiple NONTEMPORAL clauses
+  !ERROR: List item 'b' present at multiple NONTEMPORAL clauses
+  !$omp simd nontemporal(a,a,b,b)
+  do i = 1, 10
+    a(i) = i
+    b(i) = i
+  end do
+  !$omp end simd
+
+  print *, a
+
+end program omp_simd