[flang-commits] [flang] [Flang][OpenMP] Correct ArrayElements in Reduction Clause (PR #196094)
Tom Eccles via flang-commits
flang-commits at lists.llvm.org
Tue Jun 30 11:55:22 PDT 2026
================
@@ -732,79 +729,104 @@ bool ReductionProcessor::processReductionArguments(
builder.getRegion().getParentOfType<fir::DoConcurrentOp>());
}
- for (const semantics::Symbol *symbol : reductionSymbols) {
+ assert((reductionObjects.empty() ||
+ reductionSymbols.size() == reductionObjects.size()) &&
+ "mismatched reduction symbol and object lists");
+
+ for (unsigned i = 0; i < reductionSymbols.size(); ++i) {
+ const Object *object =
+ reductionObjects.empty() ? nullptr : &reductionObjects[i];
+ const semantics::Symbol *symbol =
+ object ? object->sym() : reductionSymbols[i];
+ const SomeExpr *expr = object && object->ref() ? &*object->ref() : nullptr;
+ const bool isObjectExpr =
+ ReductionProcessor::isExpressionLoweredAsReductionObject(object);
+
// If a cached reduction variable exists for this symbol, reuse it.
// This ensures that composite constructs (e.g. DO SIMD) where both
// the outer wrapper (wsloop) and inner wrapper (simd) process the same
// reduction clause share the same SSA value, enabling genLoopVars()'s
// IRMapping to correctly remap inner wrapper operands to outer wrapper
- // block arguments.
- if (reductionVarCache) {
- auto it = reductionVarCache->find(symbol);
- if (it != reductionVarCache->end()) {
+ // block arguments. Array element reductions are intentionally not cached:
+ // block-argument object tracking maps their scoped uses.
+ if (reductionVarCache && !isObjectExpr) {
+ if (auto it = reductionVarCache->find(symbol);
+ it != reductionVarCache->end()) {
reductionVars.push_back(it->second);
reduceVarByRef.push_back(doReductionByRef(it->second));
continue;
}
}
- mlir::Value symVal = converter.getSymbolAddress(*symbol);
-
- if (auto declOp = symVal.getDefiningOp<hlfir::DeclareOp>())
- symVal = declOp.getBase();
-
- mlir::Type eleType;
- auto refType = mlir::dyn_cast_or_null<fir::ReferenceType>(symVal.getType());
- if (refType)
- eleType = refType.getEleTy();
- else
- eleType = symVal.getType();
-
- // all arrays must be boxed so that we have convenient access to all the
- // information needed to iterate over the array
- if (mlir::isa<fir::SequenceType>(eleType)) {
- // For Host associated symbols, use `SymbolBox` instead
- lower::SymbolBox symBox = converter.lookupOneLevelUpSymbol(*symbol);
- hlfir::Entity entity{symBox.getAddr()};
- entity = genVariableBox(currentLocation, builder, entity);
- mlir::Value box = entity.getBase();
-
- // Always pass the box by reference so that the OpenMP dialect
- // verifiers don't need to know anything about fir.box
- auto alloca =
- fir::AllocaOp::create(builder, currentLocation, box.getType());
- fir::StoreOp::create(builder, currentLocation, box, alloca);
-
- symVal = alloca;
- } else if (mlir::isa<fir::BaseBoxType>(symVal.getType())) {
- // boxed arrays are passed as values not by reference. Unfortunately,
- // we can't pass a box by value to omp.redution_declare, so turn it
- // into a reference
- auto oldIP = builder.saveInsertionPoint();
- builder.setInsertionPointToStart(builder.getAllocaBlock());
- auto alloca =
- fir::AllocaOp::create(builder, currentLocation, symVal.getType());
- builder.restoreInsertionPoint(oldIP);
- fir::StoreOp::create(builder, currentLocation, symVal, alloca);
- symVal = alloca;
- }
+ mlir::Value reductionVal;
+ mlir::Type refTy;
- // this isn't the same as the by-val and by-ref passing later in the
- // pipeline. Both styles assume that the variable is a reference at
- // this point
- assert(fir::isa_ref_type(symVal.getType()) &&
- "reduction input var is passed by reference");
- mlir::Type elementType = fir::dyn_cast_ptrEleTy(symVal.getType());
- const bool symIsVolatile = fir::isa_volatile_type(symVal.getType());
- mlir::Type refTy = fir::ReferenceType::get(elementType, symIsVolatile);
+ if (isObjectExpr) {
+ StatementContext stmtCtx;
+ hlfir::EntityWithAttributes entity = convertExprToHLFIR(
+ converter.getCurrentLocation(), converter, *expr, symMap, stmtCtx);
+ reductionVal = entity.getBase();
+ refTy = reductionVal.getType();
----------------
tblah wrote:
What is the guarantee that this ends up scalar? I wonder if there are cases where we might still need some of the processing in the else branch
https://github.com/llvm/llvm-project/pull/196094
More information about the flang-commits
mailing list