[flang-commits] [flang] [Flang] [OpenMP]Support for multiple types in declare_reduction (PR #179442)

Urvi Rav via flang-commits flang-commits at lists.llvm.org
Tue Feb 3 03:46:08 PST 2026


https://github.com/ravurvi20 created https://github.com/llvm/llvm-project/pull/179442

Fixes [#178614](https://github.com/llvm/llvm-project/issues/178614)

This PR implements support for multiple types in OpenMP declare reduction directives, as specified in OpenMP Spec(`6.0-7.6.14declare_reduction Directive`).
When a declare reduction directive specifies several types (e.g.,` !$omp declare reduction(name: integer, real : ...)`), separate reduction operations are now generated for each type.

Modified `flang/lib/Lower/OpenMP/OpenMP.cpp` to:

- Loop through each type in the type list
- Generate a separate omp.declare_reduction operation for each type


>From 78994d2f68180e8d394acf59e2f885a02d16f2ae Mon Sep 17 00:00:00 2001
From: urvi-rav <urvi.rav at hpe.com>
Date: Tue, 3 Feb 2026 04:58:37 -0600
Subject: [PATCH] Support for multiple types in declare reduction

---
 flang/lib/Lower/OpenMP/OpenMP.cpp             | 38 +++++++-------
 .../Todo/multiple-types-declare_reduction.f90 | 51 +++++++++++++++++++
 2 files changed, 71 insertions(+), 18 deletions(-)
 create mode 100644 flang/test/Lower/OpenMP/Todo/multiple-types-declare_reduction.f90

diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 43c6128d46647..d6539ceb81f0c 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -3884,31 +3884,33 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
   const auto &specifier =
       DEREF(parser::omp::GetFirstArgument<parser::OmpReductionSpecifier>(
           construct.v));
-  if (std::get<parser::OmpTypeNameList>(specifier.t).v.size() > 1)
-    TODO(converter.getCurrentLocation(),
-         "multiple types in declare reduction is not yet supported");
-
-  mlir::Type reductionType = getReductionType(converter, specifier);
+  const auto &typeNameList =
+      std::get<parser::OmpTypeNameList>(specifier.t);
   List<Clause> clauses = makeClauses(construct.v.Clauses(), semaCtx);
   const clause::Combiner &combiner =
       appendCombiner(construct, clauses, semaCtx);
-
-  ReductionProcessor::GenCombinerCBTy genCombinerCB =
-      processReductionCombiner(converter, symTable, semaCtx, combiner);
-
-  ReductionProcessor::GenInitValueCBTy genInitValueCB;
-  ClauseProcessor cp(converter, semaCtx, clauses);
-  cp.processInitializer(symTable, genInitValueCB);
-
   const auto &identifier =
       std::get<parser::OmpReductionIdentifier>(specifier.t);
   const auto &designator = std::get<parser::ProcedureDesignator>(identifier.u);
   const auto &reductionName = std::get<parser::Name>(designator.u);
-  bool isByRef = ReductionProcessor::doReductionByRef(reductionType);
-  ReductionProcessor::createDeclareReductionHelper<
-      mlir::omp::DeclareReductionOp>(
-      converter, reductionName.ToString(), reductionType,
-      converter.getCurrentLocation(), isByRef, genCombinerCB, genInitValueCB);
+
+  for (const auto &typeSpec : typeNameList.v) {
+    mlir::Type reductionType = getReductionType(converter, specifier);
+    
+    ReductionProcessor::GenCombinerCBTy genCombinerCB =
+        processReductionCombiner(converter, symTable, semaCtx, combiner);
+    
+    ReductionProcessor::GenInitValueCBTy genInitValueCB;
+    ClauseProcessor cp(converter, semaCtx, clauses);
+    cp.processInitializer(symTable, genInitValueCB);
+
+    bool isByRef = ReductionProcessor::doReductionByRef(reductionType);
+    
+    ReductionProcessor::createDeclareReductionHelper<
+        mlir::omp::DeclareReductionOp>(
+        converter, reductionName.ToString(), reductionType,
+        converter.getCurrentLocation(), isByRef, genCombinerCB, genInitValueCB);
+  }
 }
 
 static void
diff --git a/flang/test/Lower/OpenMP/Todo/multiple-types-declare_reduction.f90 b/flang/test/Lower/OpenMP/Todo/multiple-types-declare_reduction.f90
new file mode 100644
index 0000000000000..e4931018b07ec
--- /dev/null
+++ b/flang/test/Lower/OpenMP/Todo/multiple-types-declare_reduction.f90
@@ -0,0 +1,51 @@
+! Test OpenMP declare reduction with integer and real types.
+! This test verifies correct lowering of user-defined reductions
+! to HLFIR and their use in OpenMP parallel loops.
+
+! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
+
+program main
+  implicit none
+  integer :: i, isum
+  real    :: rsum
+
+  !$omp declare reduction(myred: integer, real : &
+  !$omp  omp_out = omp_out + omp_in) initializer(omp_priv = 0)
+
+  isum = 0
+  rsum = 0.0
+
+  !$omp parallel do reduction(myred:isum)
+  do i = 1, 3
+     isum = isum + i
+  end do
+
+  !$omp parallel do reduction(myred:rsum)
+  do i = 1, 3
+     rsum = rsum + real(i)
+  end do
+
+  print *, isum, rsum
+end program main
+
+! Verify declare reduction is created for integer
+! CHECK-LABEL: omp.declare_reduction @myred : i32
+! CHECK: init {
+! CHECK: arith.constant 0 : i32
+! CHECK: omp.yield
+
+! Verify integer combiner uses addi
+! CHECK: combiner {
+! CHECK: arith.addi
+! CHECK: omp.yield
+
+! Verify reduction is used in first parallel loop (integer)
+! CHECK: omp.parallel
+! CHECK: omp.wsloop
+! CHECK-SAME: reduction(@myred
+
+! Verify reduction is used in second parallel loop (real)
+! CHECK: omp.parallel
+! CHECK: omp.wsloop
+! CHECK-SAME: reduction(@myred
+! CHECK: arith.addf



More information about the flang-commits mailing list