@@ -123,16 +123,15 @@ static void createCleanupRegion(Fortran::lower::AbstractConverter &converter,
123123 typeError ();
124124}
125125
126- fir::ShapeShiftOp
127- Fortran::lower::omp::getShapeShift (fir::FirOpBuilder &builder,
128- mlir::Location loc, mlir::Value box,
129- bool useDefaultLowerBounds) {
126+ fir::ShapeShiftOp Fortran::lower::omp::getShapeShift (
127+ fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value box,
128+ bool cannotHaveNonDefaultLowerBounds, bool useDefaultLowerBounds) {
130129 fir::SequenceType sequenceType = mlir::cast<fir::SequenceType>(
131130 hlfir::getFortranElementOrSequenceType (box.getType ()));
132131 const unsigned rank = sequenceType.getDimension ();
132+
133133 llvm::SmallVector<mlir::Value> lbAndExtents;
134134 lbAndExtents.reserve (rank * 2 );
135-
136135 mlir::Type idxTy = builder.getIndexType ();
137136
138137 mlir::Value oneVal;
@@ -142,7 +141,8 @@ Fortran::lower::omp::getShapeShift(fir::FirOpBuilder &builder,
142141 return oneVal;
143142 };
144143
145- if ((useDefaultLowerBounds) && !sequenceType.hasDynamicExtents ()) {
144+ if ((cannotHaveNonDefaultLowerBounds || useDefaultLowerBounds) &&
145+ !sequenceType.hasDynamicExtents ()) {
146146 // We don't need fir::BoxDimsOp if all of the extents are statically known
147147 // and we can assume default lower bounds. This helps avoids reads from the
148148 // mold arg.
@@ -273,12 +273,13 @@ class PopulateInitAndCleanupRegionsHelper {
273273 mlir::Type argType, mlir::Value scalarInitValue,
274274 mlir::Value allocatedPrivVarArg, mlir::Value moldArg,
275275 mlir::Block *initBlock, mlir::Region &cleanupRegion,
276- DeclOperationKind kind, const Fortran::semantics::Symbol *sym)
276+ DeclOperationKind kind, const Fortran::semantics::Symbol *sym,
277+ bool cannotHaveLowerBounds)
277278 : converter{converter}, builder{converter.getFirOpBuilder ()}, loc{loc},
278279 argType{argType}, scalarInitValue{scalarInitValue},
279280 allocatedPrivVarArg{allocatedPrivVarArg}, moldArg{moldArg},
280281 initBlock{initBlock}, cleanupRegion{cleanupRegion}, kind{kind},
281- sym{sym} {
282+ sym{sym}, cannotHaveNonDefaultLowerBounds{cannotHaveLowerBounds} {
282283 valType = fir::unwrapRefType (argType);
283284 }
284285
@@ -320,6 +321,10 @@ class PopulateInitAndCleanupRegionsHelper {
320321 // / Any length parameters which have been fetched for the type
321322 mlir::SmallVector<mlir::Value> lenParams;
322323
324+ // / If the source variable being privatized definitely can't have non-default
325+ // / lower bounds then we don't need to generate code to read them.
326+ bool cannotHaveNonDefaultLowerBounds;
327+
323328 void createYield (mlir::Value ret) {
324329 builder.create <mlir::omp::YieldOp>(loc, ret);
325330 }
@@ -457,7 +462,8 @@ void PopulateInitAndCleanupRegionsHelper::initAndCleanupBoxedArray(
457462 // Special case for (possibly allocatable) arrays of polymorphic types
458463 // e.g. !fir.class<!fir.heap<!fir.array<?x!fir.type<>>>>
459464 if (source.isPolymorphic ()) {
460- fir::ShapeShiftOp shape = getShapeShift (builder, loc, source);
465+ fir::ShapeShiftOp shape =
466+ getShapeShift (builder, loc, source, cannotHaveNonDefaultLowerBounds);
461467 mlir::Type arrayType = source.getElementOrSequenceType ();
462468 mlir::Value allocatedArray = builder.create <fir::AllocMemOp>(
463469 loc, arrayType, /* typeparams=*/ mlir::ValueRange{}, shape.getExtents ());
@@ -505,8 +511,8 @@ void PopulateInitAndCleanupRegionsHelper::initAndCleanupBoxedArray(
505511 // Put the temporary inside of a box:
506512 // hlfir::genVariableBox doesn't handle non-default lower bounds
507513 mlir::Value box;
508- fir::ShapeShiftOp shapeShift =
509- getShapeShift (builder, loc, getLoadedMoldArg () );
514+ fir::ShapeShiftOp shapeShift = getShapeShift (builder, loc, getLoadedMoldArg (),
515+ cannotHaveNonDefaultLowerBounds );
510516 mlir::Type boxType = getLoadedMoldArg ().getType ();
511517 if (mlir::isa<fir::BaseBoxType>(temp.getType ()))
512518 // the box created by the declare form createTempFromMold is missing
@@ -641,10 +647,10 @@ void Fortran::lower::omp::populateByRefInitAndCleanupRegions(
641647 mlir::Type argType, mlir::Value scalarInitValue, mlir::Block *initBlock,
642648 mlir::Value allocatedPrivVarArg, mlir::Value moldArg,
643649 mlir::Region &cleanupRegion, DeclOperationKind kind,
644- const Fortran::semantics::Symbol *sym) {
650+ const Fortran::semantics::Symbol *sym, bool cannotHaveLowerBounds ) {
645651 PopulateInitAndCleanupRegionsHelper helper (
646652 converter, loc, argType, scalarInitValue, allocatedPrivVarArg, moldArg,
647- initBlock, cleanupRegion, kind, sym);
653+ initBlock, cleanupRegion, kind, sym, cannotHaveLowerBounds );
648654 helper.populateByRefInitAndCleanupRegions ();
649655
650656 // Often we load moldArg to check something (e.g. length parameters, shape)
0 commit comments