[llvm] 103cef9 - [flang][OpenMP] Initial support for DEPTH clause (#182288)

via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 20 09:05:24 PST 2026


Author: Krzysztof Parzyszek
Date: 2026-02-20T11:05:19-06:00
New Revision: 103cef9e4fce49ab0dbb329b0aa18cf64896bae7

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

LOG: [flang][OpenMP] Initial support for DEPTH clause (#182288)

The semantic checks do not check any conditions on the associated loop
nest (such as actual depth or whether it is a perfect nest). Lowering
will emit a not-implemented-yet message.

Added: 
    flang/test/Lower/OpenMP/Todo/depth-clause.f90
    flang/test/Parser/OpenMP/depth-clause.f90
    flang/test/Semantics/OpenMP/depth-clause.f90

Modified: 
    flang/include/flang/Lower/OpenMP/Clauses.h
    flang/lib/Lower/OpenMP/Clauses.cpp
    flang/lib/Lower/OpenMP/OpenMP.cpp
    flang/lib/Parser/openmp-parsers.cpp
    flang/lib/Semantics/check-omp-loop.cpp
    llvm/include/llvm/Frontend/OpenMP/ClauseT.h
    llvm/include/llvm/Frontend/OpenMP/OMP.td

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Lower/OpenMP/Clauses.h b/flang/include/flang/Lower/OpenMP/Clauses.h
index 4fd6863b69f74..a325e74327240 100644
--- a/flang/include/flang/Lower/OpenMP/Clauses.h
+++ b/flang/include/flang/Lower/OpenMP/Clauses.h
@@ -221,6 +221,7 @@ using Counts = tomp::clause::CountsT<TypeTy, IdTy, ExprTy>;
 using Default = tomp::clause::DefaultT<TypeTy, IdTy, ExprTy>;
 using Defaultmap = tomp::clause::DefaultmapT<TypeTy, IdTy, ExprTy>;
 using Depend = tomp::clause::DependT<TypeTy, IdTy, ExprTy>;
+using Depth = tomp::clause::DepthT<TypeTy, IdTy, ExprTy>;
 using Destroy = tomp::clause::DestroyT<TypeTy, IdTy, ExprTy>;
 using Detach = tomp::clause::DetachT<TypeTy, IdTy, ExprTy>;
 using Device = tomp::clause::DeviceT<TypeTy, IdTy, ExprTy>;

diff  --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp
index fd7e3468ed504..92a98152c5cc6 100644
--- a/flang/lib/Lower/OpenMP/Clauses.cpp
+++ b/flang/lib/Lower/OpenMP/Clauses.cpp
@@ -735,6 +735,12 @@ Depend makeDepend(const parser::OmpDependClause::TaskDep &inp,
 
 // Depobj: empty
 
+Depth make(const parser::OmpClause::Depth &inp,
+           semantics::SemanticsContext &semaCtx) {
+  // inp.v -> parser::ScalarIntConstantExpr
+  return Depth{/*DepthExpr=*/makeExpr(inp.v, semaCtx)};
+}
+
 Destroy make(const parser::OmpClause::Destroy &inp,
              semantics::SemanticsContext &semaCtx) {
   // inp.v -> std::optional<OmpDestroyClause>

diff  --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 6d93f245228a8..6533c459001de 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -2307,6 +2307,7 @@ static void genFuseOp(Fortran::lower::AbstractConverter &converter,
   mlir::omp::LooprangeClauseOps looprangeClause;
   ClauseProcessor cp(converter, semaCtx, item->clauses);
   bool looprange = cp.processLooprange(stmtCtx, looprangeClause, count);
+  cp.processTODO<clause::Depth>(loc, llvm::omp::Directive::OMPD_fuse);
 
   llvm::SmallVector<mlir::Value> applyees;
   for (auto &child : eval.getNestedEvaluations()) {

diff  --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 80962c211b2f5..7838173d791a1 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1458,6 +1458,8 @@ TYPE_PARSER( //
                         parenthesized(Parser<OmpDefaultmapClause>{}))) ||
     "DEPEND" >> construct<OmpClause>(construct<OmpClause::Depend>(
                     parenthesized(Parser<OmpDependClause>{}))) ||
+    "DEPTH" >> construct<OmpClause>(construct<OmpClause::Depth>(
+                   parenthesized(scalarIntConstantExpr))) ||
     "DESTROY" >>
         construct<OmpClause>(construct<OmpClause::Destroy>(maybe(parenthesized(
             construct<OmpDestroyClause>(Parser<OmpObject>{}))))) ||

diff  --git a/flang/lib/Semantics/check-omp-loop.cpp b/flang/lib/Semantics/check-omp-loop.cpp
index 15e4d5e0d899c..5dc1adea28a2e 100644
--- a/flang/lib/Semantics/check-omp-loop.cpp
+++ b/flang/lib/Semantics/check-omp-loop.cpp
@@ -718,6 +718,12 @@ void OmpStructureChecker::Leave(const parser::OmpEndLoopDirective &x) {
   }
 }
 
+void OmpStructureChecker::Enter(const parser::OmpClause::Depth &x) {
+  CheckAllowedClause(llvm::omp::Clause::OMPC_depth);
+
+  RequiresConstantPositiveParameter(llvm::omp::Clause::OMPC_depth, x.v);
+}
+
 void OmpStructureChecker::Enter(const parser::OmpClause::Ordered &x) {
   CheckAllowedClause(llvm::omp::Clause::OMPC_ordered);
 

diff  --git a/flang/test/Lower/OpenMP/Todo/depth-clause.f90 b/flang/test/Lower/OpenMP/Todo/depth-clause.f90
new file mode 100644
index 0000000000000..efc3c77caeb6c
--- /dev/null
+++ b/flang/test/Lower/OpenMP/Todo/depth-clause.f90
@@ -0,0 +1,18 @@
+!RUN: %not_todo_cmd bbc -emit-hlfir -fopenmp -fopenmp-version=61 -o - %s 2>&1 | FileCheck %s
+!RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=61 -o - %s 2>&1 | FileCheck %s
+
+!CHECK: not yet implemented: Unhandled clause DEPTH in FUSE construct
+subroutine f00
+  integer :: i, j
+  !$omp fuse depth(2)
+  do i = 1, 10
+    do j = 1, 10
+    end do
+  end do
+  do i = 1, 10
+    do j = 1, 10
+    end do
+  end do
+  !$omp end fuse
+end
+

diff  --git a/flang/test/Parser/OpenMP/depth-clause.f90 b/flang/test/Parser/OpenMP/depth-clause.f90
new file mode 100644
index 0000000000000..168391cc01a6d
--- /dev/null
+++ b/flang/test/Parser/OpenMP/depth-clause.f90
@@ -0,0 +1,38 @@
+!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=61 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s
+!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=61 %s | FileCheck --check-prefix="PARSE-TREE" %s
+
+subroutine f00
+  integer :: i, j
+  !$omp fuse depth(2)
+  do i = 1, 10
+    do j = 1, 10
+    end do
+  end do
+  do i = 1, 10
+    do j = 1, 10
+    end do
+  end do
+  !$omp end fuse
+end
+
+!UNPARSE: SUBROUTINE f00
+!UNPARSE:  INTEGER i, j
+!UNPARSE: !$OMP FUSE DEPTH(2_4)
+!UNPARSE:  DO i=1_4,10_4
+!UNPARSE:   DO j=1_4,10_4
+!UNPARSE:   END DO
+!UNPARSE:  END DO
+!UNPARSE:  DO i=1_4,10_4
+!UNPARSE:   DO j=1_4,10_4
+!UNPARSE:   END DO
+!UNPARSE:  END DO
+!UNPARSE: !$OMP END FUSE
+!UNPARSE: END SUBROUTINE
+
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct
+!PARSE-TREE: | OmpBeginLoopDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = fuse
+!PARSE-TREE: | | OmpClauseList -> OmpClause -> Depth -> Scalar -> Integer -> Constant ->
+!PARSE-TREE:  = '2_4'
+!PARSE-TREE: | | | LiteralConstant -> IntLiteralConstant = '2'
+!PARSE-TREE: | | Flags = {}

diff  --git a/flang/test/Semantics/OpenMP/depth-clause.f90 b/flang/test/Semantics/OpenMP/depth-clause.f90
new file mode 100644
index 0000000000000..ab2b2aad46222
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/depth-clause.f90
@@ -0,0 +1,17 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=61
+
+subroutine f00(n)
+  integer :: n
+  integer :: i, j
+  !ERROR: Must be a constant value
+  !$omp fuse depth(n)
+  do i = 1, 10
+    do j = 1, 10
+    end do
+  end do
+  do i = 1, 10
+    do j = 1, 10
+    end do
+  end do
+  !$omp end fuse
+end

diff  --git a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
index 844aa932d859e..3f4502bf73a47 100644
--- a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
+++ b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
@@ -539,6 +539,14 @@ struct DependT {
   std::tuple<DependenceType, OPT(Iterator), LocatorList> t;
 };
 
+// [tr14:212-213]
+template <typename T, typename I, typename E> //
+struct DepthT {
+  using DepthExpr = E;
+  using WrapperTrait = std::true_type;
+  DepthExpr v;
+};
+
 // V5.2: [3.5] `destroy` clause
 template <typename T, typename I, typename E> //
 struct DestroyT {
@@ -1416,7 +1424,7 @@ using WrapperClausesT = std::variant<
     AbsentT<T, I, E>, AlignT<T, I, E>, AllocatorT<T, I, E>,
     AtomicDefaultMemOrderT<T, I, E>, AtT<T, I, E>, BindT<T, I, E>,
     CollapseT<T, I, E>, CombinerT<T, I, E>, ContainsT<T, I, E>,
-    CopyinT<T, I, E>, CopyprivateT<T, I, E>, DefaultT<T, I, E>,
+    CopyinT<T, I, E>, CopyprivateT<T, I, E>, DefaultT<T, I, E>, DepthT<T, I, E>,
     DestroyT<T, I, E>, DetachT<T, I, E>, DeviceSafesyncT<T, I, E>,
     DeviceTypeT<T, I, E>, DynamicAllocatorsT<T, I, E>, EnterT<T, I, E>,
     ExclusiveT<T, I, E>, FailT<T, I, E>, FilterT<T, I, E>, FinalT<T, I, E>,

diff  --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index b30c5507ecd13..865cad7769554 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -159,6 +159,9 @@ def OMPC_Depobj : Clause<[Spelling<"depobj">]> {
   let clangClass = "OMPDepobjClause";
   let isImplicit = true;
 }
+def OMPC_Depth : Clause<[Spelling<"depth">]> {
+  let flangClass = "ScalarIntConstantExpr";
+}
 def OMPC_Destroy : Clause<[Spelling<"destroy">]> {
   let clangClass = "OMPDestroyClause";
   let flangClass = "OmpDestroyClause";
@@ -966,7 +969,10 @@ def OMP_Groupprivate : Directive<[Spelling<"groupprivate">]> {
   let languages = [L_C, L_Fortran];
 }
 def OMP_Fuse : Directive<[Spelling<"fuse">]> {
-  let allowedOnceClauses = [VersionedClause<OMPC_LoopRange, 60>];
+  let allowedOnceClauses = [
+    VersionedClause<OMPC_Depth, 61>,
+    VersionedClause<OMPC_LoopRange, 60>,
+  ];
   let association = AS_LoopSeq;
   let category = CA_Executable;
 }


        


More information about the llvm-commits mailing list