[flang-commits] [flang] f5d3470 - [flang][OpenMP] Allow structure component in `task depend` clauses (#141923)

via flang-commits flang-commits at lists.llvm.org
Thu May 29 21:22:32 PDT 2025


Author: Kareem Ergawy
Date: 2025-05-30T06:22:29+02:00
New Revision: f5d3470d425f9ee99436bfdc0c1ae1ce03bab385

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

LOG: [flang][OpenMP] Allow structure component in `task depend` clauses (#141923)

Even though the spec (version 5.2) prohibits strcuture components from
being specified in `depend` clauses, this restriction is not sensible.

This PR rectifies the issue by lifting that restriction and allowing
structure components in `depend` clauses (which is allowed by OpenMP
6.0).

Added: 
    flang/test/Lower/OpenMP/task-depend-structure-component.f90

Modified: 
    flang/include/flang/Evaluate/tools.h
    flang/lib/Lower/OpenMP/ClauseProcessor.cpp
    flang/lib/Semantics/check-omp-structure.cpp

Removed: 
    flang/test/Semantics/OpenMP/depend02.f90


################################################################################
diff  --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h
index 7f2e91ae128bd..4dce1257a6507 100644
--- a/flang/include/flang/Evaluate/tools.h
+++ b/flang/include/flang/Evaluate/tools.h
@@ -414,6 +414,16 @@ const Symbol *IsArrayElement(const Expr<T> &expr, bool intoSubstring = true,
   return nullptr;
 }
 
+template <typename T>
+bool isStructureComponent(const Fortran::evaluate::Expr<T> &expr) {
+  if (auto dataRef{ExtractDataRef(expr, /*intoSubstring=*/false)}) {
+    const Fortran::evaluate::DataRef *ref{&*dataRef};
+    return std::holds_alternative<Fortran::evaluate::Component>(ref->u);
+  }
+
+  return false;
+}
+
 template <typename A>
 std::optional<NamedEntity> ExtractNamedEntity(const A &x) {
   if (auto dataRef{ExtractDataRef(x)}) {

diff  --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index a1fff6c5b7d90..f9a6f9506f510 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -947,6 +947,11 @@ bool ClauseProcessor::processDepend(lower::SymMap &symMap,
               converter.getCurrentLocation(), converter, expr, symMap, stmtCtx);
           dependVar = entity.getBase();
         }
+      } else if (evaluate::isStructureComponent(*object.ref())) {
+        SomeExpr expr = *object.ref();
+        hlfir::EntityWithAttributes entity = convertExprToHLFIR(
+            converter.getCurrentLocation(), converter, expr, symMap, stmtCtx);
+        dependVar = entity.getBase();
       } else {
         semantics::Symbol *sym = object.sym();
         dependVar = converter.getSymbolAddress(*sym);

diff  --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index b0bc478d96a1e..76dfd40c6a62c 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -5494,12 +5494,8 @@ void OmpStructureChecker::CheckDependList(const parser::DataRef &d) {
             // Check if the base element is valid on Depend Clause
             CheckDependList(elem.value().base);
           },
-          [&](const common::Indirection<parser::StructureComponent> &) {
-            context_.Say(GetContext().clauseSource,
-                "A variable that is part of another variable "
-                "(such as an element of a structure) but is not an array "
-                "element or an array section cannot appear in a DEPEND "
-                "clause"_err_en_US);
+          [&](const common::Indirection<parser::StructureComponent> &comp) {
+            CheckDependList(comp.value().base);
           },
           [&](const common::Indirection<parser::CoindexedNamedObject> &) {
             context_.Say(GetContext().clauseSource,

diff  --git a/flang/test/Lower/OpenMP/task-depend-structure-component.f90 b/flang/test/Lower/OpenMP/task-depend-structure-component.f90
new file mode 100644
index 0000000000000..7cf6dbfac2729
--- /dev/null
+++ b/flang/test/Lower/OpenMP/task-depend-structure-component.f90
@@ -0,0 +1,21 @@
+! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
+
+subroutine depend
+   type :: my_struct
+       integer :: my_component(10)
+   end type
+
+   type(my_struct) :: my_var
+
+   !$omp task depend(in:my_var%my_component)
+   !$omp end task
+end subroutine depend
+
+! CHECK: %[[VAR_ALLOC:.*]] = fir.alloca !fir.type<{{.*}}my_struct{{.*}}> {bindc_name = "my_var", {{.*}}}
+! CHECK: %[[VAR_DECL:.*]]:2 = hlfir.declare %[[VAR_ALLOC]]
+
+! CHECK: %[[COMP_SELECTOR:.*]] = hlfir.designate %[[VAR_DECL]]#0{"my_component"}
+
+! CHECK: omp.task depend(taskdependin -> %[[COMP_SELECTOR]] : {{.*}}) {
+! CHECK:   omp.terminator
+! CHECK: }

diff  --git a/flang/test/Semantics/OpenMP/depend02.f90 b/flang/test/Semantics/OpenMP/depend02.f90
deleted file mode 100644
index 76c02c8f9cbab..0000000000000
--- a/flang/test/Semantics/OpenMP/depend02.f90
+++ /dev/null
@@ -1,49 +0,0 @@
-! RUN: %python %S/../test_errors.py %s %flang -fopenmp
-! OpenMP Version 4.5
-! 2.13.9 Depend Clause
-! A variable that is part of another variable
-! (such as an element of a structure) but is not an array element or
-! an array section cannot appear in a DEPEND clause
-
-subroutine vec_mult(N)
-  implicit none
-  integer :: i, N
-  real, allocatable :: p(:), v1(:), v2(:)
-
-  type my_type
-    integer :: a(10)
-  end type my_type
-
-  type(my_type) :: my_var
-  allocate( p(N), v1(N), v2(N) )
-
-  !$omp parallel num_threads(2)
-  !$omp single
-
-  !$omp task depend(out:v1)
-  call init(v1, N)
-  !$omp end task
-
-  !$omp task depend(out:v2)
-  call init(v2, N)
-  !$omp end task
-
-  !ERROR: A variable that is part of another variable (such as an element of a structure) but is not an array element or an array section cannot appear in a DEPEND clause
-  !$omp target nowait depend(in:v1,v2, my_var%a) depend(out:p) &
-  !$omp& map(to:v1,v2) map(from: p)
-  !$omp parallel do
-  do i=1,N
-    p(i) = v1(i) * v2(i)
-  end do
-  !$omp end target
-
-  !$omp task depend(in:p)
-  call output(p, N)
-  !$omp end task
-
-  !$omp end single
-  !$omp end parallel
-
-  deallocate( p, v1, v2 )
-
-end subroutine


        


More information about the flang-commits mailing list