From 7aa8a9f1abe2e0133febe015ac502737b06828f4 Mon Sep 17 00:00:00 2001 From: Valentin Clement Date: Wed, 25 Jan 2023 09:17:27 +0100 Subject: [PATCH] [flang] Fix bounds array creation for pointer remapping calls `PointerAssociateRemapping` expect a descriptor holding a newRank x 2 array of int64. The previous lowering was wrong. Adapt the lowering to fit the expectation of the runtime. Use the `bounds` to get the rank. Reviewed By: PeteSteinfeld Differential Revision: https://reviews.llvm.org/D142487 --- flang/lib/Lower/Bridge.cpp | 20 +++++++++++++------- flang/runtime/pointer.cpp | 3 +-- flang/test/Lower/polymorphic.f90 | 40 +++++++++++++++++++++------------------- 3 files changed, 35 insertions(+), 28 deletions(-) diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index c8971ea..9c20786 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -2647,25 +2647,31 @@ private: assert(lbounds.size() && ubounds.size()); mlir::Type indexTy = builder->getIndexType(); mlir::Type boundArrayTy = fir::SequenceType::get( - {static_cast(lbounds.size()) * 2}, builder->getI64Type()); + {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 * 2))})); + 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 * 2 + 1))})); + 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() * 2); - mlir::Value shapeOp = builder->genShape(loc, {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); Fortran::lower::genPointerAssociateRemapping(*builder, loc, lhs, rhs, diff --git a/flang/runtime/pointer.cpp b/flang/runtime/pointer.cpp index 06ef736..763348d 100644 --- a/flang/runtime/pointer.cpp +++ b/flang/runtime/pointer.cpp @@ -88,13 +88,12 @@ void RTNAME(PointerAssociateLowerBounds)(Descriptor &pointer, void RTNAME(PointerAssociateRemapping)(Descriptor &pointer, const Descriptor &target, const Descriptor &bounds, const char *sourceFile, int sourceLine) { - int rank{pointer.rank()}; pointer = target; pointer.raw().attribute = CFI_attribute_pointer; Terminator terminator{sourceFile, sourceLine}; SubscriptValue byteStride{/*captured from first dimension*/}; std::size_t boundElementBytes{bounds.ElementBytes()}; - for (int j{0}; j < rank; ++j) { + for (int j{0}; j < bounds.rank(); ++j) { auto &dim{pointer.GetDimension(j)}; dim.SetBounds(GetInt64(bounds.ZeroBasedIndexedElement(2 * j), boundElementBytes, terminator), diff --git a/flang/test/Lower/polymorphic.f90 b/flang/test/Lower/polymorphic.f90 index cded60f..bcdd4d5 100644 --- a/flang/test/Lower/polymorphic.f90 +++ b/flang/test/Lower/polymorphic.f90 @@ -400,36 +400,38 @@ module polymorphic_test ! CHECK: %[[C10_1:.*]] = arith.constant 10 : 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<4xi64> -! CHECK: %[[ARRAY:.*]] = fir.undefined !fir.array<4xi64> -! CHECK: %[[ARRAY0:.*]] = fir.insert_value %[[ARRAY]], %[[C1_0]], [0 : index] : (!fir.array<4xi64>, i64) -> !fir.array<4xi64> -! CHECK: %[[ARRAY1:.*]] = fir.insert_value %[[ARRAY0]], %[[C10_0]], [1 : index] : (!fir.array<4xi64>, i64) -> !fir.array<4xi64> -! CHECK: %[[ARRAY2:.*]] = fir.insert_value %[[ARRAY1]], %[[C1_1]], [2 : index] : (!fir.array<4xi64>, i64) -> !fir.array<4xi64> -! CHECK: %[[ARRAY3:.*]] = fir.insert_value %[[ARRAY2]], %[[C10_1]], [3 : index] : (!fir.array<4xi64>, i64) -> !fir.array<4xi64> -! CHECK: fir.store %[[ARRAY3]] to %[[BOUND_ARRAY]] : !fir.ref> -! CHECK: %[[C4:.*]] = arith.constant 4 : index -! CHECK: %[[BOUND_ARRAY_SHAPE:.*]] = fir.shape %[[C4]] : (index) -> !fir.shape<1> -! CHECK: %[[BOXED_BOUND_ARRAY:.*]] = fir.embox %[[BOUND_ARRAY]](%[[BOUND_ARRAY_SHAPE]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> +! 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: %[[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: %[[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 -! 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 ! CHECK: %[[C0:.*]] = arith.constant 0 : i64 ! 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<2xi64> -! CHECK: %[[ARRAY:.*]] = fir.undefined !fir.array<2xi64> -! CHECK: %[[ARRAY0:.*]] = fir.insert_value %[[ARRAY]], %[[C0]], [0 : index] : (!fir.array<2xi64>, i64) -> !fir.array<2xi64> -! CHECK: %[[ARRAY1:.*]] = fir.insert_value %[[ARRAY0]], %[[C99]], [1 : index] : (!fir.array<2xi64>, i64) -> !fir.array<2xi64> -! CHECK: fir.store %[[ARRAY1]] to %[[BOUND_ARRAY]] : !fir.ref> +! 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: %[[C1:.*]] = arith.constant 1 : index ! CHECK: %[[C2:.*]] = arith.constant 2 : index -! CHECK: %[[BOUND_ARRAY_SHAPE:.*]] = fir.shape %[[C2]] : (index) -> !fir.shape<1> -! CHECK: %[[BOXED_BOUND_ARRAY:.*]] = fir.embox %[[BOUND_ARRAY]](%[[BOUND_ARRAY_SHAPE]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> +! 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: %[[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() -- 2.7.4