Skip to content

Conversation

ergawy
Copy link
Member

@ergawy ergawy commented Aug 26, 2025

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.

@llvmbot llvmbot added flang Flang issues not falling into any other category flang:fir-hlfir labels Aug 26, 2025
@ergawy ergawy requested review from skatrak, mjklemm and vzakhari August 26, 2025 05:17
@llvmbot
Copy link
Member

llvmbot commented Aug 26, 2025

@llvm/pr-subscribers-flang-fir-hlfir

Author: Kareem Ergawy (ergawy)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/155355.diff

3 Files Affected:

  • (modified) flang/include/flang/Optimizer/OpenMP/Passes.td (+1-1)
  • (modified) flang/lib/Optimizer/OpenMP/DoConcurrentConversion.cpp (+25-23)
  • (added) flang/test/Transforms/DoConcurrent/reduction_symbol_resultion.f90 (+34)
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:         }
+
+

@ergawy ergawy force-pushed the users/ergawy/dc_conv_reduction_sym_resultion branch from 009bcaf to 084374e Compare August 26, 2025 05:19
Copy link
Contributor

@mjklemm mjklemm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

ompReducer.getCleanupRegion());
std::string ompReducerName = sym.getLeafReference().str() + ".omp";

auto ompReducer = mlir::SymbolTable::lookupNearestSymbolFrom<
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the prompt fix, Kareem!

This method may be expensive. Please use SymbolTable object (https://mlir.llvm.org/doxygen/classmlir_1_1SymbolTable.html) to cache the module symbol table, and then use it to insert/lookup the reducer symbols.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review. Done in ef29557.

ergawy added 2 commits August 26, 2025 23:35
… 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.
@ergawy ergawy force-pushed the users/ergawy/dc_conv_reduction_sym_resultion branch from 084374e to ef29557 Compare August 27, 2025 05:11
Copy link
Contributor

@vzakhari vzakhari left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@ergawy ergawy merged commit 319705d into main Aug 27, 2025
9 checks passed
@ergawy ergawy deleted the users/ergawy/dc_conv_reduction_sym_resultion branch August 27, 2025 15:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:fir-hlfir flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[flang] Failure with do_concurrent: redefinition of symbol named 'add_reduction_f64.omp'
4 participants