[flang-commits] [flang] [Flang][OpenMP] Fix crash and IR errors for user-defined reduction on allocatable variables (PR #186765)

via flang-commits flang-commits at lists.llvm.org
Tue Jul 21 23:27:52 PDT 2026


================
@@ -803,6 +804,185 @@ bool ReductionProcessor::processReductionArguments(
                          &redOperator.u)) {
         if (!ReductionProcessor::supportedIntrinsicProcReduction(
                 *reductionIntrinsic)) {
+          if (isByRef) {
+            // create a new declare_reduction for the boxed type, reusing
+            // the existing init and combiner
+            semantics::Symbol *sym = reductionIntrinsic->v.sym();
+            llvm::StringRef baseName = {sym->name().begin(),
+                                        sym->name().size()};
+            mlir::ModuleOp module = builder.getModule();
+            auto existingDecl = module.lookupSymbol<OpType>(baseName);
+            if (!existingDecl) {
+              TODO(currentLocation,
+                   "User-defined reductions on allocatable or pointer "
+                   "variables: cannot find base reduction declaration");
+            }
+
+            std::string byrefName = getReductionName(
+                baseName, builder.getKindMap(), redType, isByRef);
+
+            mlir::Region &existingInitRegion =
+                existingDecl.getInitializerRegion();
+            auto genInitValueCB =
+                [&existingInitRegion](fir::FirOpBuilder &builder,
+                                      mlir::Location loc, mlir::Type elemTy,
+                                      mlir::Value) -> mlir::Value {
+              // unwrap box type to get the scalar element type
+              mlir::Type scalarTy = unwrapSeqOrBoxedType(elemTy);
+              // find a constant-producing op in the existing init region
+              mlir::Operation *constOp = nullptr;
+              existingInitRegion.walk([&](mlir::Operation *op) {
+                if (constOp)
+                  return;
+                if (auto arithConst =
+                        mlir::dyn_cast<mlir::arith::ConstantOp>(op)) {
+                  if (arithConst.getType() == scalarTy)
+                    constOp = op;
+                  return;
+                }
+                if (mlir::isa<fir::StringLitOp>(op)) {
+                  constOp = op;
+                  return;
+                }
+                if (mlir::isa<fir::AddrOfOp>(op)) {
+                  constOp = op;
+                  return;
+                }
+              });
+
+              if (constOp) {
+                mlir::IRMapping mapper;
+                mlir::Value cloned =
+                    builder.clone(*constOp, mapper)->getResult(0);
+                // load if the cloned op produces a reference
+                if (fir::isa_ref_type(cloned.getType()))
+                  cloned = fir::LoadOp::create(builder, loc, cloned);
+                if (cloned.getType() != scalarTy)
+                  cloned = builder.createConvert(loc, scalarTy, cloned);
+                return cloned;
+              }
+              // Fallback: zero-initialize for trivial types.
+              if (fir::isa_integer(scalarTy))
+                return builder.createIntegerConstant(loc, scalarTy, 0);
+              if (mlir::isa<mlir::FloatType>(scalarTy))
+                return builder.createRealConstant(loc, scalarTy,
+                                                  llvm::APFloat(0.0));
----------------
Ritanya-B-Bharadwaj wrote:

Fixed it.

https://github.com/llvm/llvm-project/pull/186765


More information about the flang-commits mailing list