diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -2625,6 +2625,42 @@ Fortran::lower::associateMutableBox(*this, loc, lhs, assign.rhs, lbounds, stmtCtx); } + + // Create the 2 x newRank array with the bounds to be passed to the runtime as + // a descriptor. + mlir::Value createBoundArray(llvm::ArrayRef lbounds, + llvm::ArrayRef ubounds, + mlir::Location loc) { + assert(lbounds.size() && ubounds.size()); + mlir::Type indexTy = builder->getIndexType(); + mlir::Type boundArrayTy = fir::SequenceType::get( + {2, static_cast(lbounds.size())}, builder->getI64Type()); + mlir::Value boundArray = builder->create(loc, boundArrayTy); + mlir::Value array = builder->create(loc, boundArrayTy); + for (unsigned i = 0; i < lbounds.size(); ++i) { + array = builder->create( + loc, boundArrayTy, array, lbounds[i], + builder->getArrayAttr( + {builder->getIntegerAttr(builder->getIndexType(), 0), + builder->getIntegerAttr(builder->getIndexType(), + static_cast(i))})); + array = builder->create( + loc, boundArrayTy, array, ubounds[i], + builder->getArrayAttr( + {builder->getIntegerAttr(builder->getIndexType(), 1), + builder->getIntegerAttr(builder->getIndexType(), + static_cast(i))})); + } + builder->create(loc, array, boundArray); + mlir::Type boxTy = fir::BoxType::get(boundArrayTy); + mlir::Value ext = + builder->createIntegerConstant(loc, indexTy, lbounds.size()); + mlir::Value c2 = builder->createIntegerConstant(loc, indexTy, 2); + llvm::SmallVector shapes = {c2, ext}; + mlir::Value shapeOp = builder->genShape(loc, shapes); + return builder->create(loc, boxTy, boundArray, shapeOp); + } + // Pointer assignment with bounds-remapping. R1036: a bounds-remapping is a // pair, lower bound and upper bound. void genPointerAssignment( @@ -2653,39 +2689,7 @@ mlir::Value lhs = genExprMutableBox(loc, assign.lhs).getAddr(); mlir::Value rhs = fir::getBase(genExprBox(loc, assign.rhs, stmtCtx)); - - // Create the newRank x 2 array with the bounds to be passed to - // the runtime as a descriptor. - assert(lbounds.size() && ubounds.size()); - mlir::Type indexTy = builder->getIndexType(); - mlir::Type boundArrayTy = fir::SequenceType::get( - {static_cast(lbounds.size()), 2}, builder->getI64Type()); - mlir::Value boundArray = - builder->create(loc, boundArrayTy); - mlir::Value array = builder->create(loc, boundArrayTy); - for (unsigned i = 0; i < lbounds.size(); ++i) { - array = builder->create( - loc, boundArrayTy, array, lbounds[i], - builder->getArrayAttr( - {builder->getIntegerAttr(builder->getIndexType(), - static_cast(i)), - builder->getIntegerAttr(builder->getIndexType(), 0)})); - array = builder->create( - loc, boundArrayTy, array, ubounds[i], - builder->getArrayAttr( - {builder->getIntegerAttr(builder->getIndexType(), - static_cast(i)), - builder->getIntegerAttr(builder->getIndexType(), 1)})); - } - builder->create(loc, array, boundArray); - mlir::Type boxTy = fir::BoxType::get(boundArrayTy); - mlir::Value ext = - builder->createIntegerConstant(loc, indexTy, lbounds.size()); - mlir::Value c2 = builder->createIntegerConstant(loc, indexTy, 2); - llvm::SmallVector shapes = {ext, c2}; - mlir::Value shapeOp = builder->genShape(loc, shapes); - mlir::Value boundsDesc = - builder->create(loc, boxTy, boundArray, shapeOp); + mlir::Value boundsDesc = createBoundArray(lbounds, ubounds, loc); Fortran::lower::genPointerAssociateRemapping(*builder, loc, lhs, rhs, boundsDesc); return; diff --git a/flang/test/Lower/polymorphic.f90 b/flang/test/Lower/polymorphic.f90 --- a/flang/test/Lower/polymorphic.f90 +++ b/flang/test/Lower/polymorphic.f90 @@ -403,13 +403,13 @@ ! CHECK: %[[BOUND_ARRAY:.*]] = fir.alloca !fir.array<2x2xi64> ! CHECK: %[[ARRAY:.*]] = fir.undefined !fir.array<2x2xi64> ! CHECK: %[[ARRAY0:.*]] = fir.insert_value %[[ARRAY]], %[[C1_0]], [0 : index, 0 : index] : (!fir.array<2x2xi64>, i64) -> !fir.array<2x2xi64> -! CHECK: %[[ARRAY1:.*]] = fir.insert_value %[[ARRAY0]], %[[C10_0]], [0 : index, 1 : index] : (!fir.array<2x2xi64>, i64) -> !fir.array<2x2xi64> -! CHECK: %[[ARRAY2:.*]] = fir.insert_value %[[ARRAY1]], %[[C1_1]], [1 : index, 0 : index] : (!fir.array<2x2xi64>, i64) -> !fir.array<2x2xi64> +! CHECK: %[[ARRAY1:.*]] = fir.insert_value %[[ARRAY0]], %[[C10_0]], [1 : index, 0 : index] : (!fir.array<2x2xi64>, i64) -> !fir.array<2x2xi64> +! CHECK: %[[ARRAY2:.*]] = fir.insert_value %[[ARRAY1]], %[[C1_1]], [0 : index, 1 : index] : (!fir.array<2x2xi64>, i64) -> !fir.array<2x2xi64> ! CHECK: %[[ARRAY3:.*]] = fir.insert_value %[[ARRAY2]], %[[C10_1]], [1 : index, 1 : index] : (!fir.array<2x2xi64>, i64) -> !fir.array<2x2xi64> ! CHECK: fir.store %[[ARRAY3]] to %[[BOUND_ARRAY]] : !fir.ref> ! CHECK: %[[C2_0:.*]] = arith.constant 2 : index ! CHECK: %[[C2_1:.*]] = arith.constant 2 : index -! CHECK: %[[BOUND_ARRAY_SHAPE:.*]] = fir.shape %[[C2_0]], %[[C2_1]] : (index, index) -> !fir.shape<2> +! CHECK: %[[BOUND_ARRAY_SHAPE:.*]] = fir.shape %[[C2_1]], %[[C2_0]] : (index, index) -> !fir.shape<2> ! CHECK: %[[BOXED_BOUND_ARRAY:.*]] = fir.embox %[[BOUND_ARRAY]](%[[BOUND_ARRAY_SHAPE]]) : (!fir.ref>, !fir.shape<2>) -> !fir.box> ! CHECK: %[[ARG0:.*]] = fir.convert %[[P]] : (!fir.ref>>>>) -> !fir.ref> ! CHECK: %[[ARG1:.*]] = fir.convert %[[REBOX_A]] : (!fir.class>>) -> !fir.box @@ -420,18 +420,18 @@ ! CHECK: %[[C99:.*]] = arith.constant 99 : i64 ! CHECK: %[[LOAD_A:.*]] = fir.load %[[A]] : !fir.ref>>>> ! CHECK: %[[REBOX_A:.*]] = fir.rebox %[[LOAD_A]](%{{.*}}) : (!fir.class>>>, !fir.shift<1>) -> !fir.class>> -! CHECK: %[[BOUND_ARRAY:.*]] = fir.alloca !fir.array<1x2xi64> -! CHECK: %[[ARRAY:.*]] = fir.undefined !fir.array<1x2xi64> -! CHECK: %[[ARRAY0:.*]] = fir.insert_value %[[ARRAY]], %[[C0]], [0 : index, 0 : index] : (!fir.array<1x2xi64>, i64) -> !fir.array<1x2xi64> -! CHECK: %[[ARRAY1:.*]] = fir.insert_value %[[ARRAY0]], %[[C99]], [0 : index, 1 : index] : (!fir.array<1x2xi64>, i64) -> !fir.array<1x2xi64> -! CHECK: fir.store %[[ARRAY1]] to %[[BOUND_ARRAY]] : !fir.ref> +! CHECK: %[[BOUND_ARRAY:.*]] = fir.alloca !fir.array<2x1xi64> +! CHECK: %[[ARRAY:.*]] = fir.undefined !fir.array<2x1xi64> +! CHECK: %[[ARRAY0:.*]] = fir.insert_value %[[ARRAY]], %[[C0]], [0 : index, 0 : index] : (!fir.array<2x1xi64>, i64) -> !fir.array<2x1xi64> +! CHECK: %[[ARRAY1:.*]] = fir.insert_value %[[ARRAY0]], %[[C99]], [1 : index, 0 : index] : (!fir.array<2x1xi64>, i64) -> !fir.array<2x1xi64> +! CHECK: fir.store %[[ARRAY1]] to %[[BOUND_ARRAY]] : !fir.ref> ! CHECK: %[[C1:.*]] = arith.constant 1 : index ! CHECK: %[[C2:.*]] = arith.constant 2 : index -! CHECK: %[[BOUND_ARRAY_SHAPE:.*]] = fir.shape %[[C1]], %[[C2]] : (index, index) -> !fir.shape<2> -! CHECK: %[[BOXED_BOUND_ARRAY:.*]] = fir.embox %[[BOUND_ARRAY]](%[[BOUND_ARRAY_SHAPE]]) : (!fir.ref>, !fir.shape<2>) -> !fir.box> +! CHECK: %[[BOUND_ARRAY_SHAPE:.*]] = fir.shape %[[C2]], %[[C1]] : (index, index) -> !fir.shape<2> +! CHECK: %[[BOXED_BOUND_ARRAY:.*]] = fir.embox %[[BOUND_ARRAY]](%[[BOUND_ARRAY_SHAPE]]) : (!fir.ref>, !fir.shape<2>) -> !fir.box> ! CHECK: %[[ARG0:.*]] = fir.convert %[[Q]] : (!fir.ref>>>>) -> !fir.ref> ! CHECK: %[[ARG1:.*]] = fir.convert %[[REBOX_A]] : (!fir.class>>) -> !fir.box -! CHECK: %[[ARG2:.*]] = fir.convert %[[BOXED_BOUND_ARRAY]] : (!fir.box>) -> !fir.box +! CHECK: %[[ARG2:.*]] = fir.convert %[[BOXED_BOUND_ARRAY]] : (!fir.box>) -> !fir.box ! CHECK: %{{.*}} = fir.call @_FortranAPointerAssociateRemapping(%[[ARG0]], %[[ARG1]], %[[ARG2]], %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, !fir.box, !fir.box, !fir.ref, i32) -> none subroutine test_elemental_assign()