[flang] [llvm] [flang][mlir] Add flang to mlir lowering for dyn_groupprivate (PR #180938)

via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 11 05:14:49 PST 2026


https://github.com/skc7 created https://github.com/llvm/llvm-project/pull/180938

None

>From 37ace282ac9d179e2a22333bf9dc607a82d8d868 Mon Sep 17 00:00:00 2001
From: skc7 <Krishna.Sankisa at amd.com>
Date: Wed, 11 Feb 2026 18:41:48 +0530
Subject: [PATCH] [flang][mlir] Add flang to mlir lowering for dyn_groupprivate

---
 flang/lib/Lower/OpenMP/ClauseProcessor.cpp    | 47 ++++++++++++++++
 flang/lib/Lower/OpenMP/ClauseProcessor.h      |  4 +-
 flang/lib/Lower/OpenMP/OpenMP.cpp             |  6 ++-
 .../OpenMP/Todo/dyn-groupprivate-clause.f90   | 10 ----
 .../Lower/OpenMP/dyn-groupprivate-clause.f90  | 54 +++++++++++++++++++
 .../Frontend/OpenMP/ConstructDecompositionT.h | 18 +++++++
 6 files changed, 126 insertions(+), 13 deletions(-)
 delete mode 100644 flang/test/Lower/OpenMP/Todo/dyn-groupprivate-clause.f90
 create mode 100644 flang/test/Lower/OpenMP/dyn-groupprivate-clause.f90

diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index b1973a3b8bf06..856d8c6a3f8cc 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -689,6 +689,53 @@ bool ClauseProcessor::processThreadLimit(
   return false;
 }
 
+bool ClauseProcessor::processDynGroupprivate(
+    lower::StatementContext &stmtCtx,
+    mlir::omp::DynGroupprivateClauseOps &result) const {
+  using DynGroupprivate = omp::clause::DynGroupprivate;
+  if (auto *clause = findUniqueClause<DynGroupprivate>()) {
+    fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
+    mlir::MLIRContext *context = firOpBuilder.getContext();
+
+    // Process AccessGroup modifier (cgroup)
+    if (auto accessGroup =
+            std::get<std::optional<DynGroupprivate::AccessGroup>>(clause->t)) {
+      switch (*accessGroup) {
+      case DynGroupprivate::AccessGroup::Cgroup:
+        result.accessGroup = mlir::omp::AccessGroupModifierAttr::get(
+            context, mlir::omp::AccessGroupModifier::cgroup);
+        break;
+      }
+    }
+
+    // Process Fallback modifier (abort, default_mem, null)
+    if (auto fallback =
+            std::get<std::optional<DynGroupprivate::Fallback>>(clause->t)) {
+      switch (*fallback) {
+      case DynGroupprivate::Fallback::Abort:
+        result.fallback = mlir::omp::FallbackModifierAttr::get(
+            context, mlir::omp::FallbackModifier::abort);
+        break;
+      case DynGroupprivate::Fallback::Default_Mem:
+        result.fallback = mlir::omp::FallbackModifierAttr::get(
+            context, mlir::omp::FallbackModifier::default_mem);
+        break;
+      case DynGroupprivate::Fallback::Null:
+        result.fallback = mlir::omp::FallbackModifierAttr::get(
+            context, mlir::omp::FallbackModifier::null);
+        break;
+      }
+    }
+
+    // Process size expression
+    const auto &sizeExpr = std::get<SomeExpr>(clause->t);
+    result.dynGroupprivateSize =
+        fir::getBase(converter.genExprValue(sizeExpr, stmtCtx));
+    return true;
+  }
+  return false;
+}
+
 bool ClauseProcessor::processUntied(mlir::omp::UntiedClauseOps &result) const {
   return markClauseOccurrence<omp::clause::Untied>(result.untied);
 }
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h
index ca9b28dfdd061..c2a4f88dab4bf 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.h
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h
@@ -116,7 +116,9 @@ class ClauseProcessor {
   bool processThreadLimit(lower::StatementContext &stmtCtx,
                           mlir::omp::ThreadLimitClauseOps &result) const;
   bool processUntied(mlir::omp::UntiedClauseOps &result) const;
-
+  bool
+  processDynGroupprivate(lower::StatementContext &stmtCtx,
+                         mlir::omp::DynGroupprivateClauseOps &result) const;
   bool processDetach(mlir::omp::DetachClauseOps &result) const;
   // 'Repeatable' clauses: They can appear multiple times in the clause list.
   bool processAffinity(mlir::omp::AffinityClauseOps &result) const;
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 3eeaab48d1447..835b6f068631c 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -1739,7 +1739,7 @@ static void genTargetClauses(
                 &mapSyms);
   cp.processNowait(clauseOps);
   cp.processThreadLimit(stmtCtx, clauseOps);
-
+  cp.processDynGroupprivate(stmtCtx, clauseOps);
   cp.processTODO<clause::Allocate, clause::InReduction, clause::UsesAllocators>(
       loc, llvm::omp::Directive::OMPD_target);
 
@@ -1878,6 +1878,7 @@ static void genTeamsClauses(
   }
 
   cp.processReduction(loc, clauseOps, reductionSyms);
+  cp.processDynGroupprivate(stmtCtx, clauseOps);
   // TODO Support delayed privatization.
 }
 
@@ -4234,7 +4235,8 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
         !std::holds_alternative<clause::Untied>(clause.u) &&
         !std::holds_alternative<clause::TaskReduction>(clause.u) &&
         !std::holds_alternative<clause::Detach>(clause.u) &&
-        !std::holds_alternative<clause::Device>(clause.u)) {
+        !std::holds_alternative<clause::Device>(clause.u) &&
+        !std::holds_alternative<clause::DynGroupprivate>(clause.u)) {
       std::string name =
           parser::ToUpperCaseLetters(llvm::omp::getOpenMPClauseName(clause.id));
       if (!semaCtx.langOptions().OpenMPSimd)
diff --git a/flang/test/Lower/OpenMP/Todo/dyn-groupprivate-clause.f90 b/flang/test/Lower/OpenMP/Todo/dyn-groupprivate-clause.f90
deleted file mode 100644
index e06470f772bf8..0000000000000
--- a/flang/test/Lower/OpenMP/Todo/dyn-groupprivate-clause.f90
+++ /dev/null
@@ -1,10 +0,0 @@
-!RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=61 -o - %s 2>&1 | FileCheck %s
-
-!CHECK: not yet implemented: DYN_GROUPPRIVATE clause is not implemented yet
-subroutine f00(n)
-  implicit none
-  integer :: n
-  !$omp target dyn_groupprivate(n)
-  !$omp end target
-end
-
diff --git a/flang/test/Lower/OpenMP/dyn-groupprivate-clause.f90 b/flang/test/Lower/OpenMP/dyn-groupprivate-clause.f90
new file mode 100644
index 0000000000000..93c04374827df
--- /dev/null
+++ b/flang/test/Lower/OpenMP/dyn-groupprivate-clause.f90
@@ -0,0 +1,54 @@
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=61 -o - %s 2>&1 | FileCheck %s
+
+! Test lowering of dyn_groupprivate clause for target directive
+
+! CHECK-LABEL: func.func @_QPf00
+! CHECK: omp.target dyn_groupprivate({{.*}})
+subroutine f00(n)
+  implicit none
+  integer :: n
+  !$omp target dyn_groupprivate(n)
+  !$omp end target
+end subroutine
+
+! CHECK-LABEL: func.func @_QPf01
+! CHECK: omp.target dyn_groupprivate(fallback(abort), {{.*}})
+subroutine f01(n)
+  implicit none
+  integer :: n
+  !$omp target dyn_groupprivate(fallback(abort): n)
+  !$omp end target
+end subroutine
+
+! CHECK-LABEL: func.func @_QPf02
+! CHECK: omp.target dyn_groupprivate(cgroup, fallback(default_mem), {{.*}})
+subroutine f02(n)
+  implicit none
+  integer :: n
+  !$omp target dyn_groupprivate(cgroup, fallback(default_mem): n)
+  !$omp end target
+end subroutine
+
+! Test lowering of dyn_groupprivate clause for teams directive
+
+! CHECK-LABEL: func.func @_QPf03
+! CHECK: omp.teams dyn_groupprivate({{.*}})
+subroutine f03(n)
+  implicit none
+  integer :: n
+  integer :: x
+  !$omp teams dyn_groupprivate(n)
+  x = 1
+  !$omp end teams
+end subroutine
+
+! CHECK-LABEL: func.func @_QPf04
+! CHECK: omp.teams dyn_groupprivate(cgroup, fallback(null), {{.*}})
+subroutine f04(n)
+  implicit none
+  integer :: n
+  integer :: x
+  !$omp teams dyn_groupprivate(cgroup, fallback(null): n)
+  x = 1
+  !$omp end teams
+end subroutine
diff --git a/llvm/include/llvm/Frontend/OpenMP/ConstructDecompositionT.h b/llvm/include/llvm/Frontend/OpenMP/ConstructDecompositionT.h
index 3a9690149ddde..54e71e9e7e391 100644
--- a/llvm/include/llvm/Frontend/OpenMP/ConstructDecompositionT.h
+++ b/llvm/include/llvm/Frontend/OpenMP/ConstructDecompositionT.h
@@ -259,6 +259,9 @@ struct ConstructDecompositionT {
   bool
   applyClause(const tomp::clause::ThreadLimitT<TypeTy, IdTy, ExprTy> &clause,
               const ClauseTy *);
+  bool applyClause(
+      const tomp::clause::DynGroupprivateT<TypeTy, IdTy, ExprTy> &clause,
+      const ClauseTy *);
 
   uint32_t version;
   HelperType &helper;
@@ -1149,6 +1152,21 @@ bool ConstructDecompositionT<C, H>::applyClause(
   return true;
 }
 
+// DYN_GROUPPRIVATE
+// [6.1] dyn_groupprivate clause
+// Directives: target, teams
+//
+// The effect of the dyn_groupprivate clause is as if it is applied to the
+// outermost leaf construct that permits it.
+template <typename C, typename H>
+bool ConstructDecompositionT<C, H>::applyClause(
+    const tomp::clause::DynGroupprivateT<TypeTy, IdTy, ExprTy> &clause,
+    const ClauseTy *node) {
+  if (!applyToOutermost(node))
+    return error(node, ErrorCode::NoLeafAllowing);
+  return true;
+}
+
 // --- Splitting ------------------------------------------------------
 
 template <typename C, typename H> bool ConstructDecompositionT<C, H>::split() {



More information about the llvm-commits mailing list