[flang-commits] [flang] 7d7633b - [Flang][OpenMP][OpenACC] Error for loop with no control

Kiran Chandramohan via flang-commits flang-commits at lists.llvm.org
Mon Feb 27 08:55:39 PST 2023


Author: Kiran Chandramohan
Date: 2023-02-27T16:52:50Z
New Revision: 7d7633bdf489eff66a56984a4cf3d6a21cf36f2b

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

LOG: [Flang][OpenMP][OpenACC] Error for loop with no control

Issue error if a DO construct associated with a loop does not have
loop control. Currently, it is issued only for the loop immediately
following the loop construct. This patch extends it to cases like
collapse where there is more than one loop associated. It also fixes
a crash since the existing code always expects loop control.

This is covered in OpenMP 4.5 standard, Section 2.7.1.
"The do-loop cannot be a DO WHILE or a DO loop without loop control."

OpenACC 3.3 covers this indirectly in Section 2.9.1.
The trip count for all loops associated with the collapse clause must
be computable and invariant in all the loops".

Reviewed By: clementval

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

Added: 
    flang/test/Semantics/OpenMP/omp-do-collapse1.f90

Modified: 
    flang/lib/Semantics/resolve-directives.cpp
    flang/test/Semantics/OpenACC/acc-loop.f90
    flang/test/Semantics/OpenMP/do-collapse.f90

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 6c876ec69db60..f16f53c578b22 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -97,7 +97,7 @@ template <typename T> class DirectiveAttributeVisitor {
     dataSharingAttributeObjects_.clear();
   }
   bool HasDataSharingAttributeObject(const Symbol &);
-  const parser::Name &GetLoopIndex(const parser::DoConstruct &);
+  const parser::Name *GetLoopIndex(const parser::DoConstruct &);
   const parser::DoConstruct *GetDoConstructIf(
       const parser::ExecutionPartConstruct &);
   Symbol *DeclarePrivateAccessEntity(
@@ -560,10 +560,19 @@ bool DirectiveAttributeVisitor<T>::HasDataSharingAttributeObject(
 }
 
 template <typename T>
-const parser::Name &DirectiveAttributeVisitor<T>::GetLoopIndex(
+const parser::Name *DirectiveAttributeVisitor<T>::GetLoopIndex(
     const parser::DoConstruct &x) {
   using Bounds = parser::LoopControl::Bounds;
-  return std::get<Bounds>(x.GetLoopControl()->u).name.thing;
+  if (x.GetLoopControl()) {
+    return &std::get<Bounds>(x.GetLoopControl()->u).name.thing;
+  } else {
+    context_
+        .Say(std::get<parser::Statement<parser::NonLabelDoStmt>>(x.t).source,
+            "Loop control is not present in the DO LOOP"_err_en_US)
+        .Attach(GetContext().directiveSource,
+            "associated with the enclosing LOOP construct"_en_US);
+    return nullptr;
+  }
 }
 
 template <typename T>
@@ -893,11 +902,13 @@ void AccAttributeVisitor::PrivatizeAssociatedLoopIndex(
   const auto &outer{std::get<std::optional<parser::DoConstruct>>(x.t)};
   for (const parser::DoConstruct *loop{&*outer}; loop && level > 0; --level) {
     // go through all the nested do-loops and resolve index variables
-    const parser::Name &iv{GetLoopIndex(*loop)};
-    if (auto *symbol{ResolveAcc(iv, ivDSA, currScope())}) {
-      symbol->set(Symbol::Flag::AccPreDetermined);
-      iv.symbol = symbol; // adjust the symbol within region
-      AddToContextObjectWithDSA(*symbol, ivDSA);
+    const parser::Name *iv{GetLoopIndex(*loop)};
+    if (iv) {
+      if (auto *symbol{ResolveAcc(*iv, ivDSA, currScope())}) {
+        symbol->set(Symbol::Flag::AccPreDetermined);
+        iv->symbol = symbol; // adjust the symbol within region
+        AddToContextObjectWithDSA(*symbol, ivDSA);
+      }
     }
 
     const auto &block{std::get<parser::Block>(loop->t)};
@@ -1278,20 +1289,21 @@ bool OmpAttributeVisitor::Pre(const parser::DoConstruct &x) {
   // TODO:[OpenMP 5.1] DO CONCURRENT indices are private
   if (x.IsDoNormal()) {
     if (!dirContext_.empty() && GetContext().withinConstruct) {
-      if (const auto &iv{GetLoopIndex(x)}; iv.symbol) {
-        if (!iv.symbol->test(Symbol::Flag::OmpPreDetermined)) {
-          ResolveSeqLoopIndexInParallelOrTaskConstruct(iv);
+      const parser::Name *iv{GetLoopIndex(x)};
+      if (iv && iv->symbol) {
+        if (!iv->symbol->test(Symbol::Flag::OmpPreDetermined)) {
+          ResolveSeqLoopIndexInParallelOrTaskConstruct(*iv);
         } else {
           // TODO: conflict checks with explicitly determined DSA
         }
         ordCollapseLevel--;
         if (ordCollapseLevel) {
-          if (const auto *details{iv.symbol->detailsIf<HostAssocDetails>()}) {
+          if (const auto *details{iv->symbol->detailsIf<HostAssocDetails>()}) {
             const Symbol *tpSymbol = &details->symbol();
             if (tpSymbol->test(Symbol::Flag::OmpThreadprivate)) {
-              context_.Say(iv.source,
+              context_.Say(iv->source,
                   "Loop iteration variable %s is not allowed in THREADPRIVATE."_err_en_US,
-                  iv.ToString());
+                  iv->ToString());
             }
           }
         }
@@ -1362,16 +1374,18 @@ void OmpAttributeVisitor::PrivatizeAssociatedLoopIndexAndCheckLoopLevel(
   const auto &outer{std::get<std::optional<parser::DoConstruct>>(x.t)};
   for (const parser::DoConstruct *loop{&*outer}; loop && level > 0; --level) {
     // go through all the nested do-loops and resolve index variables
-    const parser::Name &iv{GetLoopIndex(*loop)};
-    if (auto *symbol{ResolveOmp(iv, ivDSA, currScope())}) {
-      symbol->set(Symbol::Flag::OmpPreDetermined);
-      iv.symbol = symbol; // adjust the symbol within region
-      AddToContextObjectWithDSA(*symbol, ivDSA);
-    }
+    const parser::Name *iv{GetLoopIndex(*loop)};
+    if (iv) {
+      if (auto *symbol{ResolveOmp(*iv, ivDSA, currScope())}) {
+        symbol->set(Symbol::Flag::OmpPreDetermined);
+        iv->symbol = symbol; // adjust the symbol within region
+        AddToContextObjectWithDSA(*symbol, ivDSA);
+      }
 
-    const auto &block{std::get<parser::Block>(loop->t)};
-    const auto it{block.begin()};
-    loop = it != block.end() ? GetDoConstructIf(*it) : nullptr;
+      const auto &block{std::get<parser::Block>(loop->t)};
+      const auto it{block.begin()};
+      loop = it != block.end() ? GetDoConstructIf(*it) : nullptr;
+    }
   }
   CheckAssocLoopLevel(level, GetAssociatedClause());
 }

diff  --git a/flang/test/Semantics/OpenACC/acc-loop.f90 b/flang/test/Semantics/OpenACC/acc-loop.f90
index 75e09958909cd..371569b861872 100644
--- a/flang/test/Semantics/OpenACC/acc-loop.f90
+++ b/flang/test/Semantics/OpenACC/acc-loop.f90
@@ -250,4 +250,11 @@ program openacc_loop_validity
   end do
   !$acc end parallel
 
+  !$acc loop collapse(2)
+  do i = 1, N
+    !ERROR: Loop control is not present in the DO LOOP
+    do
+      a(i) = 3.14
+    end do
+  end do
 end program openacc_loop_validity

diff  --git a/flang/test/Semantics/OpenMP/do-collapse.f90 b/flang/test/Semantics/OpenMP/do-collapse.f90
index bc5412b3f9037..145b7b75d28df 100644
--- a/flang/test/Semantics/OpenMP/do-collapse.f90
+++ b/flang/test/Semantics/OpenMP/do-collapse.f90
@@ -22,5 +22,12 @@ program omp_doCollapse
       !$omp end do
     end do
   end do
+
+  !$omp parallel do collapse(2)
+    do i = 1, 3
+      !ERROR: Loop control is not present in the DO LOOP
+      do
+      end do
+    end do
 end program omp_doCollapse
 

diff  --git a/flang/test/Semantics/OpenMP/omp-do-collapse1.f90 b/flang/test/Semantics/OpenMP/omp-do-collapse1.f90
new file mode 100644
index 0000000000000..81f87d8239e53
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/omp-do-collapse1.f90
@@ -0,0 +1,14 @@
+! RUN: not %flang_fc1 -fdebug-unparse-with-symbols -fopenmp %s 2>&1 | FileCheck %s
+! OpenMP Version 4.5
+! 2.7.1 Loop Construct
+program omp_doCollapse
+  integer:: i
+  !$omp parallel do collapse(2)
+    do i = 1, 3
+      !CHECK: Loop control is not present in the DO LOOP
+      !CHECK: associated with the enclosing LOOP construct
+      do
+      end do
+    end do
+end program omp_doCollapse
+


        


More information about the flang-commits mailing list