[flang-commits] [flang] 7dc18a6 - [flang][OpenMP] Added semantic checks for hint clause

Nimish Mishra via flang-commits flang-commits at lists.llvm.org
Thu Jul 14 05:55:56 PDT 2022


Author: Nimish Mishra
Date: 2022-07-14T18:24:57+05:30
New Revision: 7dc18a62e40e241019ec77e70f01bc41d39ab748

URL: https://github.com/llvm/llvm-project/commit/7dc18a62e40e241019ec77e70f01bc41d39ab748
DIFF: https://github.com/llvm/llvm-project/commit/7dc18a62e40e241019ec77e70f01bc41d39ab748.diff

LOG: [flang][OpenMP] Added semantic checks for hint clause

This patch improves semantic checks for hint clause.
It checks "hint-expression is a constant expression
that evaluates to a scalar value with kind
`omp_sync_hint_kind` and a value that is a valid
synchronization hint."

Reviewed By: peixin

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

Added: 
    flang/test/Semantics/OpenMP/omp-atomic-hint-clause.f90
    flang/test/Semantics/OpenMP/omp-critical-hint-clause.f90

Modified: 
    flang/lib/Semantics/check-omp-structure.cpp
    flang/lib/Semantics/check-omp-structure.h

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 6dc97eaddb952..64255d2afa004 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -314,6 +314,48 @@ void OmpStructureChecker::CheckPredefinedAllocatorRestriction(
   }
 }
 
+template <class D>
+void OmpStructureChecker::CheckHintClause(
+    D *leftOmpClauseList, D *rightOmpClauseList) {
+  auto checkForValidHintClause = [&](const D *clauseList) {
+    for (const auto &clause : clauseList->v) {
+      const Fortran::parser::OmpClause *ompClause = nullptr;
+      if constexpr (std::is_same_v<D,
+                        const Fortran::parser::OmpAtomicClauseList>) {
+        ompClause = std::get_if<Fortran::parser::OmpClause>(&clause.u);
+        if (!ompClause)
+          continue;
+      } else if constexpr (std::is_same_v<D,
+                               const Fortran::parser::OmpClauseList>) {
+        ompClause = &clause;
+      }
+      if (const Fortran::parser::OmpClause::Hint *
+          hintClause{
+              std::get_if<Fortran::parser::OmpClause::Hint>(&ompClause->u)}) {
+        std::optional<std::int64_t> hintValue = GetIntValue(hintClause->v);
+        if (hintValue && hintValue.value() >= 0) {
+          if((hintValue.value() & 0xC) == 0xC /*`omp_sync_hint_nonspeculative` and `omp_lock_hint_speculative`*/ 
+                  || (hintValue.value() & 0x3) == 0x3 /*`omp_sync_hint_uncontended` and omp_sync_hint_contended*/ )
+            context_.Say(clause.source,
+                "Hint clause value "
+                "is not a valid OpenMP synchronization value"_err_en_US);
+        } else {
+          context_.Say(clause.source,
+              "Hint clause must have non-negative constant "
+              "integer expression"_err_en_US);
+        }
+      }
+    }
+  };
+
+  if (leftOmpClauseList) {
+    checkForValidHintClause(leftOmpClauseList);
+  }
+  if (rightOmpClauseList) {
+    checkForValidHintClause(rightOmpClauseList);
+  }
+}
+
 void OmpStructureChecker::Enter(const parser::OpenMPConstruct &x) {
   // Simd Construct with Ordered Construct Nesting check
   // We cannot use CurrentDirectiveIsNested() here because
@@ -1277,6 +1319,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPCriticalConstruct &x) {
         parser::MessageFormattedText{
             "Hint clause other than omp_sync_hint_none cannot be specified for an unnamed CRITICAL directive"_err_en_US});
   }
+  CheckHintClause<const parser::OmpClauseList>(&ompClause, nullptr);
 }
 
 void OmpStructureChecker::Leave(const parser::OpenMPCriticalConstruct &) {
@@ -1580,6 +1623,9 @@ void OmpStructureChecker::Enter(const parser::OpenMPAtomicConstruct &x) {
             CheckAtomicMemoryOrderClause(
                 &std::get<parser::OmpAtomicClauseList>(atomicConstruct.t),
                 nullptr);
+            CheckHintClause<const parser::OmpAtomicClauseList>(
+                &std::get<parser::OmpAtomicClauseList>(atomicConstruct.t),
+                nullptr);
           },
           [&](const parser::OmpAtomicUpdate &atomicUpdate) {
             const auto &dir{std::get<parser::Verbatim>(atomicUpdate.t)};
@@ -1591,6 +1637,8 @@ void OmpStructureChecker::Enter(const parser::OpenMPAtomicConstruct &x) {
                     .statement);
             CheckAtomicMemoryOrderClause(
                 &std::get<0>(atomicUpdate.t), &std::get<2>(atomicUpdate.t));
+            CheckHintClause<const parser::OmpAtomicClauseList>(
+                &std::get<0>(atomicUpdate.t), &std::get<2>(atomicUpdate.t));
           },
           [&](const auto &atomicConstruct) {
             const auto &dir{std::get<parser::Verbatim>(atomicConstruct.t)};
@@ -1598,6 +1646,9 @@ void OmpStructureChecker::Enter(const parser::OpenMPAtomicConstruct &x) {
                 dir.source, llvm::omp::Directive::OMPD_atomic);
             CheckAtomicMemoryOrderClause(&std::get<0>(atomicConstruct.t),
                 &std::get<2>(atomicConstruct.t));
+            CheckHintClause<const parser::OmpAtomicClauseList>(
+                &std::get<0>(atomicConstruct.t),
+                &std::get<2>(atomicConstruct.t));
           },
       },
       x.u);

diff  --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index a4748157d04fc..0ff0b90bbe690 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -268,6 +268,7 @@ class OmpStructureChecker
   void EnterDirectiveNest(const int index) { directiveNest_[index]++; }
   void ExitDirectiveNest(const int index) { directiveNest_[index]--; }
   int GetDirectiveNest(const int index) { return directiveNest_[index]; }
+  template <typename D> void CheckHintClause(D *, D *);
 
   enum directiveNestType {
     SIMDNest,

diff  --git a/flang/test/Semantics/OpenMP/omp-atomic-hint-clause.f90 b/flang/test/Semantics/OpenMP/omp-atomic-hint-clause.f90
new file mode 100644
index 0000000000000..048dd978eed56
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/omp-atomic-hint-clause.f90
@@ -0,0 +1,105 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp 
+! Semantic checks on hint clauses, as they appear on atomic constructs
+
+program sample
+    use omp_lib
+    integer :: x, y
+    logical :: z
+    real :: k
+    integer :: p(1)
+    integer, parameter :: a = 1
+    !$omp atomic hint(1) write
+        y = 2
+    
+    !$omp atomic read hint(2)
+        y = x    
+     
+    !ERROR: Hint clause value is not a valid OpenMP synchronization value
+    !$omp atomic hint(3)
+        y = y + 10
+    
+    !$omp atomic update hint(5)
+        y = x
+    
+    !ERROR: Hint clause value is not a valid OpenMP synchronization value
+    !$omp atomic hint(7) capture
+        y = x
+        x = y
+    !$omp end atomic
+   
+    !ERROR: Hint clause must have non-negative constant integer expression
+    !ERROR: Must be a constant value
+    !$omp atomic update hint(x)
+        y = y * 1
+    
+    !$omp atomic read hint(4)
+        y = x
+
+    !$omp atomic hint(8)
+        x = x * y
+
+    !$omp atomic write hint(omp_sync_hint_uncontended)
+        x = 10 * y
+
+    !$omp atomic hint(omp_lock_hint_speculative)
+        x = y + x
+    
+    !ERROR: Hint clause must have non-negative constant integer expression
+    !ERROR: Must be a constant value
+    !$omp atomic hint(omp_sync_hint_uncontended + omp_sync_hint) read
+        y = x 
+
+    !$omp atomic hint(omp_sync_hint_nonspeculative)
+        y = y * 9
+
+    !$omp atomic hint(omp_sync_hint_none) read
+        y = x
+
+    !$omp atomic read hint(omp_sync_hint_uncontended + omp_lock_hint_speculative)
+        y = x
+
+    !$omp atomic hint(omp_lock_hint_nonspeculative + omp_lock_hint_uncontended)
+        x = x * y
+
+    !$omp atomic write hint(omp_lock_hint_contended + omp_sync_hint_speculative)
+        x = 10 * y
+
+    !$omp atomic hint(omp_lock_hint_contended + omp_sync_hint_nonspeculative)
+        x = y + x
+
+    !ERROR: Hint clause value is not a valid OpenMP synchronization value
+    !$omp atomic hint(omp_sync_hint_uncontended + omp_sync_hint_contended) read
+        y = x 
+
+    !ERROR: Hint clause value is not a valid OpenMP synchronization value
+    !$omp atomic hint(omp_sync_hint_nonspeculative + omp_lock_hint_speculative)
+        y = y * 9
+
+    !ERROR: Hint clause must have non-negative constant integer expression
+    !$omp atomic hint(1.0) read
+        y = x
+
+    !ERROR: Hint clause must have non-negative constant integer expression
+    !ERROR: Operands of + must be numeric; have LOGICAL(4) and INTEGER(4)
+    !$omp atomic hint(z + omp_sync_hint_nonspeculative) read
+        y = x
+
+    !ERROR: Hint clause must have non-negative constant integer expression
+    !ERROR: Must be a constant value
+    !$omp atomic hint(k + omp_sync_hint_speculative) read
+        y = x
+
+    !ERROR: Hint clause must have non-negative constant integer expression
+    !ERROR: Must be a constant value
+    !$omp atomic hint(p(1) + omp_sync_hint_uncontended) write
+        x = 10 * y
+
+    !$omp atomic write hint(a)
+        x = y + x
+
+    !$omp atomic hint(abs(-1)) write
+        x = 7
+
+    !$omp atomic hint(omp_sync_hint_uncontended + omp_sync_hint_uncontended + omp_sync_hint_speculative) write
+        x = 7
+end program

diff  --git a/flang/test/Semantics/OpenMP/omp-critical-hint-clause.f90 b/flang/test/Semantics/OpenMP/omp-critical-hint-clause.f90
new file mode 100644
index 0000000000000..33088c6caf359
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/omp-critical-hint-clause.f90
@@ -0,0 +1,118 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp 
+! Semantic checks on hint clauses, as they appear on critical construct
+
+program sample
+    use omp_lib
+    integer :: y
+    logical :: z
+    real :: k
+    integer :: p(1)
+    
+    !$omp critical (name) hint(1)
+        y = 2
+    !$omp end critical (name)
+    
+    !$omp critical (name) hint(2)
+        y = 2
+    !$omp end critical (name)
+     
+    !ERROR: Hint clause value is not a valid OpenMP synchronization value
+    !$omp critical (name) hint(3)
+        y = 2
+    !$omp end critical (name)
+    
+    !$omp critical (name)  hint(5)
+        y = 2
+    !$omp end critical (name)
+    
+    !ERROR: Hint clause value is not a valid OpenMP synchronization value
+    !$omp critical (name) hint(7)
+        y = 2
+    !$omp end critical (name)
+   
+    !ERROR: Hint clause must have non-negative constant integer expression
+    !ERROR: Must be a constant value
+    !$omp critical (name) hint(x)
+        y = 2
+    !$omp end critical (name)
+    
+    !$omp critical (name) hint(4)
+        y = 2
+    !$omp end critical (name)
+
+    !$omp critical (name) hint(8)
+        y = 2
+    !$omp end critical (name)
+
+    !$omp critical (name) hint(omp_sync_hint_uncontended)
+        y = 2
+    !$omp end critical (name)
+
+    !$omp critical (name) hint(omp_lock_hint_speculative)
+        y = 2
+    !$omp end critical (name)
+    
+    !ERROR: Hint clause must have non-negative constant integer expression
+    !ERROR: Must be a constant value
+    !$omp critical (name) hint(omp_sync_hint_uncontended + omp_sync_hint) 
+        y = 2
+    !$omp end critical (name)
+
+    !$omp critical (name) hint(omp_sync_hint_nonspeculative)
+        y = 2
+    !$omp end critical (name)
+
+     !$omp critical (name) hint(omp_sync_hint_none)
+        y = 2
+    !$omp end critical (name)
+
+    !$omp critical (name) hint(omp_sync_hint_uncontended + omp_lock_hint_speculative)
+        y = 2
+    !$omp end critical (name)
+
+    !$omp critical (name) hint(omp_lock_hint_nonspeculative + omp_lock_hint_uncontended)
+        y = 2
+    !$omp end critical (name)
+
+    !$omp critical (name) hint(omp_lock_hint_contended + omp_sync_hint_speculative)
+        y = 2
+    !$omp end critical (name)
+
+    !$omp critical (name) hint(omp_lock_hint_contended + omp_sync_hint_nonspeculative)
+        y = 2
+    !$omp end critical (name)
+
+    !ERROR: Hint clause value is not a valid OpenMP synchronization value
+     !$omp critical (name) hint(omp_sync_hint_uncontended + omp_sync_hint_contended)
+        y = 2
+    !$omp end critical (name)
+
+    !ERROR: Hint clause value is not a valid OpenMP synchronization value
+    !$omp critical (name) hint(omp_sync_hint_nonspeculative + omp_lock_hint_speculative)
+        y = 2
+    !$omp end critical (name)
+
+    !ERROR: Hint clause must have non-negative constant integer expression
+    !$omp critical (name) hint(1.0) 
+        y = 2
+    !$omp end critical (name)
+
+    !ERROR: Hint clause must have non-negative constant integer expression
+    !ERROR: Operands of + must be numeric; have LOGICAL(4) and INTEGER(4)
+    !$omp critical (name) hint(z + omp_sync_hint_nonspeculative)
+        y = 2
+    !$omp end critical (name)
+
+    !ERROR: Hint clause must have non-negative constant integer expression
+    !ERROR: Must be a constant value
+    !$omp critical (name) hint(k + omp_sync_hint_speculative)
+        y = 2
+    !$omp end critical (name)
+
+    !ERROR: Hint clause must have non-negative constant integer expression
+    !ERROR: Must be a constant value
+    !$omp critical (name) hint(p(1) + omp_sync_hint_uncontended)
+        y = 2
+    !$omp end critical (name)
+end program
+


        


More information about the flang-commits mailing list