summaryrefslogtreecommitdiffstats
path: root/flang/lib/Lower/OpenMP/ReductionProcessor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Lower/OpenMP/ReductionProcessor.cpp')
-rw-r--r--flang/lib/Lower/OpenMP/ReductionProcessor.cpp31
1 files changed, 27 insertions, 4 deletions
diff --git a/flang/lib/Lower/OpenMP/ReductionProcessor.cpp b/flang/lib/Lower/OpenMP/ReductionProcessor.cpp
index 0d05ca5aee65..c1c94119fd90 100644
--- a/flang/lib/Lower/OpenMP/ReductionProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ReductionProcessor.cpp
@@ -13,6 +13,7 @@
#include "ReductionProcessor.h"
#include "flang/Lower/AbstractConverter.h"
+#include "flang/Lower/SymbolMap.h"
#include "flang/Optimizer/Builder/HLFIRTools.h"
#include "flang/Optimizer/Builder/Todo.h"
#include "flang/Optimizer/Dialect/FIRType.h"
@@ -522,12 +523,20 @@ void ReductionProcessor::addDeclareReduction(
if (reductionSymbols)
reductionSymbols->push_back(symbol);
mlir::Value symVal = converter.getSymbolAddress(*symbol);
- auto redType = mlir::cast<fir::ReferenceType>(symVal.getType());
+ 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>(redType.getEleTy())) {
- hlfir::Entity entity{symVal};
+ if (mlir::isa<fir::SequenceType>(eleType)) {
+ // For Host associated symbols, use `SymbolBox` instead
+ Fortran::lower::SymbolBox symBox =
+ converter.lookupOneLevelUpSymbol(*symbol);
+ hlfir::Entity entity{symBox.getAddr()};
entity = genVariableBox(currentLocation, builder, entity);
mlir::Value box = entity.getBase();
@@ -538,11 +547,25 @@ void ReductionProcessor::addDeclareReduction(
builder.create<fir::StoreOp>(currentLocation, box, alloca);
symVal = alloca;
- redType = mlir::cast<fir::ReferenceType>(symVal.getType());
+ } 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 alloca =
+ builder.create<fir::AllocaOp>(currentLocation, symVal.getType());
+ builder.create<fir::StoreOp>(currentLocation, symVal, alloca);
+ symVal = alloca;
} else if (auto declOp = symVal.getDefiningOp<hlfir::DeclareOp>()) {
symVal = declOp.getBase();
}
+ // 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(mlir::isa<fir::ReferenceType>(symVal.getType()) &&
+ "reduction input var is a reference");
+
reductionVars.push_back(symVal);
}
const bool isByRef = doReductionByRef(reductionVars);