diff options
Diffstat (limited to 'flang/lib/Lower/OpenMP/Utils.cpp')
-rw-r--r-- | flang/lib/Lower/OpenMP/Utils.cpp | 53 |
1 files changed, 40 insertions, 13 deletions
diff --git a/flang/lib/Lower/OpenMP/Utils.cpp b/flang/lib/Lower/OpenMP/Utils.cpp index 29cccbd..37b926e 100644 --- a/flang/lib/Lower/OpenMP/Utils.cpp +++ b/flang/lib/Lower/OpenMP/Utils.cpp @@ -14,11 +14,12 @@ #include "ClauseFinder.h" #include "flang/Evaluate/fold.h" -#include "flang/Lower/OpenMP/Clauses.h" #include <flang/Lower/AbstractConverter.h> #include <flang/Lower/ConvertType.h> #include <flang/Lower/DirectivesCommon.h> +#include <flang/Lower/OpenMP/Clauses.h> #include <flang/Lower/PFTBuilder.h> +#include <flang/Lower/Support/PrivateReductionUtils.h> #include <flang/Optimizer/Builder/FIRBuilder.h> #include <flang/Optimizer/Builder/Todo.h> #include <flang/Parser/openmp-utils.h> @@ -180,16 +181,11 @@ static void generateArrayIndices(lower::AbstractConverter &converter, for (auto v : arr->subscript()) { if (std::holds_alternative<Triplet>(v.u)) TODO(clauseLocation, "Triplet indexing in map clause is unsupported"); - auto expr = std::get<Fortran::evaluate::IndirectSubscriptIntegerExpr>(v.u); mlir::Value subscript = fir::getBase(converter.genExprValue(toEvExpr(expr.value()), stmtCtx)); - mlir::Value one = firOpBuilder.createIntegerConstant( - clauseLocation, firOpBuilder.getIndexType(), 1); - subscript = firOpBuilder.createConvert( - clauseLocation, firOpBuilder.getIndexType(), subscript); - indices.push_back(mlir::arith::SubIOp::create(firOpBuilder, clauseLocation, - subscript, one)); + indices.push_back(firOpBuilder.createConvert( + clauseLocation, firOpBuilder.getIndexType(), subscript)); } } @@ -322,10 +318,42 @@ mlir::Value createParentSymAndGenIntermediateMaps( subscriptIndices, objectList[i]); assert(!subscriptIndices.empty() && "missing expected indices for map clause"); - curValue = fir::CoordinateOp::create( - firOpBuilder, clauseLocation, - firOpBuilder.getRefType(arrType.getEleTy()), curValue, - subscriptIndices); + if (auto boxTy = llvm::dyn_cast<fir::BaseBoxType>(curValue.getType())) { + // To accommodate indexing into box types of all dimensions including + // negative dimensions we have to take into consideration the lower + // bounds and extents of the data (stored in the box) and convey it + // to the ArrayCoorOp so that it can appropriately access the element + // utilising the subscript we provide and the runtime sizes stored in + // the Box. To do so we need to generate a ShapeShiftOp which combines + // both the lb (ShiftOp) and extent (ShapeOp) of the Box, giving the + // ArrayCoorOp the spatial information it needs to calculate the + // underlying address. + mlir::Value shapeShift = Fortran::lower::getShapeShift( + firOpBuilder, clauseLocation, curValue); + auto addrOp = + fir::BoxAddrOp::create(firOpBuilder, clauseLocation, curValue); + curValue = fir::ArrayCoorOp::create( + firOpBuilder, clauseLocation, + firOpBuilder.getRefType(arrType.getEleTy()), addrOp, shapeShift, + /*slice=*/mlir::Value{}, subscriptIndices, + /*typeparms=*/mlir::ValueRange{}); + } else { + // We're required to negate by one in the non-Box case as I believe + // we do not have the shape generated from the dimensions to help + // adjust the indexing. + // TODO/FIXME: This may need adjusted to support bounds of unusual + // dimensions, if that's the case then it is likely best to fold this + // branch into the above. + mlir::Value one = firOpBuilder.createIntegerConstant( + clauseLocation, firOpBuilder.getIndexType(), 1); + for (auto &v : subscriptIndices) + v = mlir::arith::SubIOp::create(firOpBuilder, clauseLocation, v, + one); + curValue = fir::CoordinateOp::create( + firOpBuilder, clauseLocation, + firOpBuilder.getRefType(arrType.getEleTy()), curValue, + subscriptIndices); + } } } @@ -415,7 +443,6 @@ mlir::Value createParentSymAndGenIntermediateMaps( currentIndicesIdx++; } } - return curValue; } |