@@ -670,7 +670,8 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc,
670670 const std::vector<Fortran::evaluate::Subscript> &subscripts,
671671 std::stringstream &asFortran, fir::ExtendedValue &dataExv,
672672 bool dataExvIsAssumedSize, fir::factory::AddrAndBoundsInfo &info,
673- bool treatIndexAsSection = false ) {
673+ bool treatIndexAsSection = false ,
674+ bool strideIncludeLowerExtent = false ) {
674675 int dimension = 0 ;
675676 mlir::Type idxTy = builder.getIndexType ();
676677 mlir::Type boundTy = builder.getType <BoundsType>();
@@ -679,6 +680,7 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc,
679680 mlir::Value zero = builder.createIntegerConstant (loc, idxTy, 0 );
680681 mlir::Value one = builder.createIntegerConstant (loc, idxTy, 1 );
681682 const int dataExvRank = static_cast <int >(dataExv.rank ());
683+ mlir::Value cumulativeExtent = one;
682684 for (const auto &subscript : subscripts) {
683685 const auto *triplet{std::get_if<Fortran::evaluate::Triplet>(&subscript.u )};
684686 if (triplet || treatIndexAsSection) {
@@ -847,6 +849,15 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc,
847849 ubound = builder.create <mlir::arith::SubIOp>(loc, extent, one);
848850 }
849851 }
852+
853+ // When the strideInBytes is true, it means the stride is from descriptor
854+ // and this already includes the lower extents.
855+ if (strideIncludeLowerExtent && !strideInBytes) {
856+ stride = cumulativeExtent;
857+ cumulativeExtent = builder.createOrFold <mlir::arith::MulIOp>(
858+ loc, cumulativeExtent, extent);
859+ }
860+
850861 mlir::Value bound = builder.create <BoundsOp>(
851862 loc, boundTy, lbound, ubound, extent, stride, strideInBytes, baseLb);
852863 bounds.push_back (bound);
@@ -882,7 +893,8 @@ fir::factory::AddrAndBoundsInfo gatherDataOperandAddrAndBounds(
882893 const Fortran::semantics::MaybeExpr &maybeDesignator,
883894 mlir::Location operandLocation, std::stringstream &asFortran,
884895 llvm::SmallVector<mlir::Value> &bounds, bool treatIndexAsSection = false ,
885- bool unwrapFirBox = true , bool genDefaultBounds = true ) {
896+ bool unwrapFirBox = true , bool genDefaultBounds = true ,
897+ bool strideIncludeLowerExtent = false ) {
886898 using namespace Fortran ;
887899
888900 fir::factory::AddrAndBoundsInfo info;
@@ -943,7 +955,8 @@ fir::factory::AddrAndBoundsInfo gatherDataOperandAddrAndBounds(
943955 asFortran << ' (' ;
944956 bounds = genBoundsOps<BoundsOp, BoundsType>(
945957 builder, operandLocation, converter, stmtCtx, arrayRef->subscript (),
946- asFortran, dataExv, dataExvIsAssumedSize, info, treatIndexAsSection);
958+ asFortran, dataExv, dataExvIsAssumedSize, info, treatIndexAsSection,
959+ strideIncludeLowerExtent);
947960 }
948961 asFortran << ' )' ;
949962 } else if (auto compRef = detail::getRef<evaluate::Component>(designator)) {
@@ -955,7 +968,7 @@ fir::factory::AddrAndBoundsInfo gatherDataOperandAddrAndBounds(
955968 mlir::isa<fir::SequenceType>(fir::unwrapRefType (info.addr .getType ())))
956969 bounds = fir::factory::genBaseBoundsOps<BoundsOp, BoundsType>(
957970 builder, operandLocation, compExv,
958- /* isAssumedSize=*/ false );
971+ /* isAssumedSize=*/ false , strideIncludeLowerExtent );
959972 asFortran << designator.AsFortran ();
960973
961974 if (semantics::IsOptional (compRef->GetLastSymbol ())) {
@@ -1012,7 +1025,8 @@ fir::factory::AddrAndBoundsInfo gatherDataOperandAddrAndBounds(
10121025 if (genDefaultBounds &&
10131026 mlir::isa<fir::SequenceType>(fir::unwrapRefType (info.addr .getType ())))
10141027 bounds = fir::factory::genBaseBoundsOps<BoundsOp, BoundsType>(
1015- builder, operandLocation, dataExv, dataExvIsAssumedSize);
1028+ builder, operandLocation, dataExv, dataExvIsAssumedSize,
1029+ strideIncludeLowerExtent);
10161030 asFortran << symRef->get ().name ().ToString ();
10171031 } else { // Unsupported
10181032 llvm::report_fatal_error (" Unsupported type of OpenACC operand" );
0 commit comments