@@ -660,7 +660,7 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc,
660
660
Fortran::lower::StatementContext &stmtCtx,
661
661
const std::list<Fortran::parser::SectionSubscript> &subscripts,
662
662
std::stringstream &asFortran, fir::ExtendedValue &dataExv,
663
- mlir::Value baseAddr) {
663
+ mlir::Value baseAddr, bool treatIndexAsSection = false ) {
664
664
int dimension = 0 ;
665
665
mlir::Type idxTy = builder.getIndexType ();
666
666
mlir::Type boundTy = builder.getType <BoundsType>();
@@ -669,8 +669,9 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc,
669
669
mlir::Value zero = builder.createIntegerConstant (loc, idxTy, 0 );
670
670
mlir::Value one = builder.createIntegerConstant (loc, idxTy, 1 );
671
671
for (const auto &subscript : subscripts) {
672
- if (const auto *triplet{
673
- std::get_if<Fortran::parser::SubscriptTriplet>(&subscript.u )}) {
672
+ const auto *triplet{
673
+ std::get_if<Fortran::parser::SubscriptTriplet>(&subscript.u )};
674
+ if (triplet || treatIndexAsSection) {
674
675
if (dimension != 0 )
675
676
asFortran << ' ,' ;
676
677
mlir::Value lbound, ubound, extent;
@@ -689,9 +690,21 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc,
689
690
strideInBytes = true ;
690
691
}
691
692
692
- const auto &lower{std::get<0 >(triplet->t )};
693
+ const Fortran::lower::SomeExpr *lower{nullptr };
694
+ if (triplet) {
695
+ if (const auto &tripletLb{std::get<0 >(triplet->t )})
696
+ lower = Fortran::semantics::GetExpr (*tripletLb);
697
+ } else {
698
+ const auto &index {std::get<Fortran::parser::IntExpr>(subscript.u )};
699
+ lower = Fortran::semantics::GetExpr (index );
700
+ if (lower->Rank () > 0 ) {
701
+ mlir::emitError (
702
+ loc, " vector subscript cannot be used for an array section" );
703
+ break ;
704
+ }
705
+ }
693
706
if (lower) {
694
- lval = Fortran::semantics::GetIntValue ( lower);
707
+ lval = Fortran::evaluate::ToInt64 (* lower);
695
708
if (lval) {
696
709
if (defaultLb) {
697
710
lbound = builder.createIntegerConstant (loc, idxTy, *lval - 1 );
@@ -701,59 +714,66 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc,
701
714
}
702
715
asFortran << *lval;
703
716
} else {
704
- const Fortran::lower::SomeExpr *lexpr =
705
- Fortran::semantics::GetExpr (*lower);
706
717
mlir::Value lb =
707
- fir::getBase (converter.genExprValue (loc, *lexpr , stmtCtx));
718
+ fir::getBase (converter.genExprValue (loc, *lower , stmtCtx));
708
719
lb = builder.createConvert (loc, baseLb.getType (), lb);
709
720
lbound = builder.create <mlir::arith::SubIOp>(loc, lb, baseLb);
710
- asFortran << lexpr ->AsFortran ();
721
+ asFortran << lower ->AsFortran ();
711
722
}
712
723
} else {
713
724
// If the lower bound is not specified, then the section
714
725
// starts from offset 0 of the dimension.
715
726
// Note that the lowerbound in the BoundsOp is always 0-based.
716
727
lbound = zero;
717
728
}
718
- asFortran << ' :' ;
719
- const auto &upper{std::get<1 >(triplet->t )};
720
- if (upper) {
721
- uval = Fortran::semantics::GetIntValue (upper);
722
- if (uval) {
723
- if (defaultLb) {
724
- ubound = builder.createIntegerConstant (loc, idxTy, *uval - 1 );
729
+
730
+ if (!triplet) {
731
+ // If it is a scalar subscript, then the upper bound
732
+ // is equal to the lower bound, and the extent is one.
733
+ ubound = lbound;
734
+ extent = one;
735
+ } else {
736
+ asFortran << ' :' ;
737
+ const auto &upper{std::get<1 >(triplet->t )};
738
+
739
+ if (upper) {
740
+ uval = Fortran::semantics::GetIntValue (upper);
741
+ if (uval) {
742
+ if (defaultLb) {
743
+ ubound = builder.createIntegerConstant (loc, idxTy, *uval - 1 );
744
+ } else {
745
+ mlir::Value ub = builder.createIntegerConstant (loc, idxTy, *uval);
746
+ ubound = builder.create <mlir::arith::SubIOp>(loc, ub, baseLb);
747
+ }
748
+ asFortran << *uval;
725
749
} else {
726
- mlir::Value ub = builder.createIntegerConstant (loc, idxTy, *uval);
750
+ const Fortran::lower::SomeExpr *uexpr =
751
+ Fortran::semantics::GetExpr (*upper);
752
+ mlir::Value ub =
753
+ fir::getBase (converter.genExprValue (loc, *uexpr, stmtCtx));
754
+ ub = builder.createConvert (loc, baseLb.getType (), ub);
727
755
ubound = builder.create <mlir::arith::SubIOp>(loc, ub, baseLb);
756
+ asFortran << uexpr->AsFortran ();
728
757
}
729
- asFortran << *uval;
730
- } else {
731
- const Fortran::lower::SomeExpr *uexpr =
732
- Fortran::semantics::GetExpr (*upper);
733
- mlir::Value ub =
734
- fir::getBase (converter.genExprValue (loc, *uexpr, stmtCtx));
735
- ub = builder.createConvert (loc, baseLb.getType (), ub);
736
- ubound = builder.create <mlir::arith::SubIOp>(loc, ub, baseLb);
737
- asFortran << uexpr->AsFortran ();
738
758
}
739
- }
740
- if (lower && upper) {
741
- if (lval && uval && *uval < *lval) {
742
- mlir::emitError (loc, " zero sized array section" );
743
- break ;
744
- } else if (std::get<2 >(triplet->t )) {
745
- const auto &strideExpr{std::get<2 >(triplet->t )};
746
- if (strideExpr) {
747
- mlir::emitError (loc, " stride cannot be specified on "
748
- " an array section" );
759
+ if (lower && upper) {
760
+ if (lval && uval && *uval < *lval) {
761
+ mlir::emitError (loc, " zero sized array section" );
749
762
break ;
763
+ } else if (std::get<2 >(triplet->t )) {
764
+ const auto &strideExpr{std::get<2 >(triplet->t )};
765
+ if (strideExpr) {
766
+ mlir::emitError (loc, " stride cannot be specified on "
767
+ " an array section" );
768
+ break ;
769
+ }
750
770
}
751
771
}
752
- }
753
- if (!ubound) {
754
- // ub = extent - 1
755
- extent = fir::factory::readExtent (builder, loc, dataExv, dimension );
756
- ubound = builder. create <mlir::arith::SubIOp>(loc, extent, one);
772
+ if (!ubound) {
773
+ // ub = extent - 1
774
+ extent = fir::factory::readExtent (builder, loc, dataExv, dimension);
775
+ ubound = builder. create <mlir::arith::SubIOp>( loc, extent, one );
776
+ }
757
777
}
758
778
mlir::Value bound = builder.create <BoundsOp>(
759
779
loc, boundTy, lbound, ubound, extent, stride, strideInBytes, baseLb);
@@ -770,15 +790,15 @@ mlir::Value gatherDataOperandAddrAndBounds(
770
790
Fortran::semantics::SemanticsContext &semanticsContext,
771
791
Fortran::lower::StatementContext &stmtCtx, const ObjectType &object,
772
792
mlir::Location operandLocation, std::stringstream &asFortran,
773
- llvm::SmallVector<mlir::Value> &bounds) {
793
+ llvm::SmallVector<mlir::Value> &bounds, bool treatIndexAsSection = false ) {
774
794
mlir::Value baseAddr;
775
795
776
796
std::visit (
777
797
Fortran::common::visitors{
778
798
[&](const Fortran::parser::Designator &designator) {
779
799
if (auto expr{Fortran::semantics::AnalyzeExpr (semanticsContext,
780
800
designator)}) {
781
- if ((*expr).Rank () > 0 &&
801
+ if ((( *expr).Rank () > 0 || treatIndexAsSection) &&
782
802
Fortran::parser::Unwrap<Fortran::parser::ArrayElement>(
783
803
designator)) {
784
804
const auto *arrayElement =
@@ -809,7 +829,8 @@ mlir::Value gatherDataOperandAddrAndBounds(
809
829
asFortran << ' (' ;
810
830
bounds = genBoundsOps<BoundsType, BoundsOp>(
811
831
builder, operandLocation, converter, stmtCtx,
812
- arrayElement->subscripts , asFortran, dataExv, baseAddr);
832
+ arrayElement->subscripts , asFortran, dataExv, baseAddr,
833
+ treatIndexAsSection);
813
834
}
814
835
asFortran << ' )' ;
815
836
} else if (Fortran::parser::Unwrap<
@@ -845,6 +866,10 @@ mlir::Value gatherDataOperandAddrAndBounds(
845
866
if (Fortran::parser::Unwrap<Fortran::parser::ArrayElement>(
846
867
designator)) {
847
868
// Single array element.
869
+ const auto *arrayElement =
870
+ Fortran::parser::Unwrap<Fortran::parser::ArrayElement>(
871
+ designator);
872
+ (void )arrayElement;
848
873
fir::ExtendedValue compExv =
849
874
converter.genExprAddr (operandLocation, *expr, stmtCtx);
850
875
baseAddr = fir::getBase (compExv);
0 commit comments