[flang-commits] [flang] [flang] `do concurrent`: fix reduction symbol resolution when mapping to OpenMP (PR #155355)

Kareem Ergawy via flang-commits flang-commits at lists.llvm.org
Mon Aug 25 22:17:41 PDT 2025


https://github.com/ergawy created https://github.com/llvm/llvm-project/pull/155355

Fixes 155273

This PR introduces 2 changes:
1. The `do concurrent` to OpenMP pass is now a module pass rather than a function pass.
2. Reduction ops are looked up in the parent module before being created.

The benefit of using a module pass is that the same reduction operation can be used across multiple functions if the reduction type matches.

>From 009bcaf5da666e8dd95c71542a5b0880bd7de8b5 Mon Sep 17 00:00:00 2001
From: ergawy <kareem.ergawy at amd.com>
Date: Tue, 26 Aug 2025 00:13:35 -0500
Subject: [PATCH] [flang] `do concurrent`: fix reduction symbol resolution when
 mapping to OpenMP

Fixes 155273

This PR introduces 2 changes:
1. The `do concurrent` to OpenMP pass is now a module pass rather than a
   function pass.
2. Reduction ops are looked up in the parent module before being
   created.

The benefit of using a module pass is that the same reduction operation
can be used across multiple functions if the reduction type matches.
---
 .../include/flang/Optimizer/OpenMP/Passes.td  |  2 +-
 .../OpenMP/DoConcurrentConversion.cpp         | 48 ++++++++++---------
 .../reduction_symbol_resultion.f90            | 34 +++++++++++++
 3 files changed, 60 insertions(+), 24 deletions(-)
 create mode 100644 flang/test/Transforms/DoConcurrent/reduction_symbol_resultion.f90

diff --git a/flang/include/flang/Optimizer/OpenMP/Passes.td b/flang/include/flang/Optimizer/OpenMP/Passes.td
index 99202f6ee81e7..e2f092024c250 100644
--- a/flang/include/flang/Optimizer/OpenMP/Passes.td
+++ b/flang/include/flang/Optimizer/OpenMP/Passes.td
@@ -50,7 +50,7 @@ def FunctionFilteringPass : Pass<"omp-function-filtering"> {
   ];
 }
 
-def DoConcurrentConversionPass : Pass<"omp-do-concurrent-conversion", "mlir::func::FuncOp"> {
+def DoConcurrentConversionPass : Pass<"omp-do-concurrent-conversion", "mlir::ModuleOp"> {
   let summary = "Map `DO CONCURRENT` loops to OpenMP worksharing loops.";
 
   let description = [{ This is an experimental pass to map `DO CONCURRENT` loops
diff --git a/flang/lib/Optimizer/OpenMP/DoConcurrentConversion.cpp b/flang/lib/Optimizer/OpenMP/DoConcurrentConversion.cpp
index 2b3ac169e8b5b..3c08ad0a54001 100644
--- a/flang/lib/Optimizer/OpenMP/DoConcurrentConversion.cpp
+++ b/flang/lib/Optimizer/OpenMP/DoConcurrentConversion.cpp
@@ -368,22 +368,28 @@ class DoConcurrentConversion
 
         mlir::OpBuilder::InsertionGuard guard(rewriter);
         rewriter.setInsertionPointAfter(firReducer);
-
-        auto ompReducer = mlir::omp::DeclareReductionOp::create(
-            rewriter, firReducer.getLoc(),
-            sym.getLeafReference().str() + ".omp",
-            firReducer.getTypeAttr().getValue());
-
-        cloneFIRRegionToOMP(firReducer.getAllocRegion(),
-                            ompReducer.getAllocRegion());
-        cloneFIRRegionToOMP(firReducer.getInitializerRegion(),
-                            ompReducer.getInitializerRegion());
-        cloneFIRRegionToOMP(firReducer.getReductionRegion(),
-                            ompReducer.getReductionRegion());
-        cloneFIRRegionToOMP(firReducer.getAtomicReductionRegion(),
-                            ompReducer.getAtomicReductionRegion());
-        cloneFIRRegionToOMP(firReducer.getCleanupRegion(),
-                            ompReducer.getCleanupRegion());
+        std::string ompReducerName = sym.getLeafReference().str() + ".omp";
+
+        auto ompReducer = mlir::SymbolTable::lookupNearestSymbolFrom<
+            mlir::omp::DeclareReductionOp>(
+            loop, rewriter.getStringAttr(ompReducerName));
+
+        if (!ompReducer) {
+          ompReducer = mlir::omp::DeclareReductionOp::create(
+              rewriter, firReducer.getLoc(), ompReducerName,
+              firReducer.getTypeAttr().getValue());
+
+          cloneFIRRegionToOMP(firReducer.getAllocRegion(),
+                              ompReducer.getAllocRegion());
+          cloneFIRRegionToOMP(firReducer.getInitializerRegion(),
+                              ompReducer.getInitializerRegion());
+          cloneFIRRegionToOMP(firReducer.getReductionRegion(),
+                              ompReducer.getReductionRegion());
+          cloneFIRRegionToOMP(firReducer.getAtomicReductionRegion(),
+                              ompReducer.getAtomicReductionRegion());
+          cloneFIRRegionToOMP(firReducer.getCleanupRegion(),
+                              ompReducer.getCleanupRegion());
+        }
 
         wsloopClauseOps.reductionVars.push_back(op);
         wsloopClauseOps.reductionByref.push_back(byRef);
@@ -444,11 +450,7 @@ class DoConcurrentConversionPass
       : DoConcurrentConversionPassBase(options) {}
 
   void runOnOperation() override {
-    mlir::func::FuncOp func = getOperation();
-
-    if (func.isDeclaration())
-      return;
-
+    mlir::ModuleOp module = getOperation();
     mlir::MLIRContext *context = &getContext();
 
     if (mapTo != flangomp::DoConcurrentMappingKind::DCMK_Host &&
@@ -472,8 +474,8 @@ class DoConcurrentConversionPass
     target.markUnknownOpDynamicallyLegal(
         [](mlir::Operation *) { return true; });
 
-    if (mlir::failed(mlir::applyFullConversion(getOperation(), target,
-                                               std::move(patterns)))) {
+    if (mlir::failed(
+            mlir::applyFullConversion(module, target, std::move(patterns)))) {
       signalPassFailure();
     }
   }
diff --git a/flang/test/Transforms/DoConcurrent/reduction_symbol_resultion.f90 b/flang/test/Transforms/DoConcurrent/reduction_symbol_resultion.f90
new file mode 100644
index 0000000000000..1b2b8461cca63
--- /dev/null
+++ b/flang/test/Transforms/DoConcurrent/reduction_symbol_resultion.f90
@@ -0,0 +1,34 @@
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fdo-concurrent-to-openmp=host %s -o - \
+! RUN:   | FileCheck %s
+
+subroutine test1(x,s,N)
+  real :: x(N), s
+  integer :: N
+  do concurrent(i=1:N) reduce(+:s)
+     s=s+x(i)
+  end do
+end subroutine test1
+subroutine test2(x,s,N)
+  real :: x(N), s
+  integer :: N
+  do concurrent(i=1:N) reduce(+:s)
+     s=s+x(i)
+  end do
+end subroutine test2
+
+! CHECK:       omp.declare_reduction @[[RED_SYM:.*]] : f32 init
+! CHECK-NOT:   omp.declare_reduction
+
+! CHECK-LABEL: func.func @_QPtest1
+! CHECK:         omp.parallel {
+! CHECK:           omp.wsloop reduction(@[[RED_SYM]] {{.*}} : !fir.ref<f32>) {
+! CHECK:           }
+! CHECK:         }
+
+! CHECK-LABEL: func.func @_QPtest2
+! CHECK:         omp.parallel {
+! CHECK:           omp.wsloop reduction(@[[RED_SYM]] {{.*}} : !fir.ref<f32>) {
+! CHECK:           }
+! CHECK:         }
+
+



More information about the flang-commits mailing list