From 491b6a9ccb05e5e6784ce50718570d204378c75e Mon Sep 17 00:00:00 2001 From: Valentin Clement Date: Mon, 5 Dec 2022 18:28:13 +0100 Subject: [PATCH] [flang] Fix pointer association with remap on polymorphic entities Runtime is expecting a 1d array. This patch fixes the generation of the array holding the bounds to be passed to the runtime function call. Reviewed By: jeanPerier, PeteSteinfeld Differential Revision: https://reviews.llvm.org/D139324 --- flang/lib/Lower/Bridge.cpp | 33 ++++++++++++------------------ flang/test/Lower/polymorphic.f90 | 44 +++++++++++++++++++++++++++++----------- 2 files changed, 45 insertions(+), 32 deletions(-) diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index a45b325..8913cb8 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -2804,45 +2804,38 @@ private: (rhsType && rhsType->IsPolymorphic())) { if (explicitIterationSpace()) TODO(loc, "polymorphic pointer assignment in FORALL"); - + mlir::Value lhs = genExprMutableBox(loc, assign.lhs).getAddr(); mlir::Value rhs = fir::getBase(genExprBox(loc, assign.rhs, stmtCtx)); - // Create the 2xnewRank array with the bounds to be passed to + // Create the newRank x 2 array with the bounds to be passed to // the runtime as a descriptor. assert(lbounds.size() && ubounds.size()); - fir::SequenceType::Shape shape(2, lbounds.size()); mlir::Type indexTy = builder->getIndexType(); - mlir::Type boundArrayTy = - fir::SequenceType::get(shape, builder->getI64Type()); + 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); - llvm::SmallVector exts; - mlir::Value c2 = - builder->createIntegerConstant(loc, indexTy, 2); 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(), - static_cast(0))})); + builder->getArrayAttr({builder->getIntegerAttr( + builder->getIndexType(), static_cast(i * 2))})); array = builder->create( loc, boundArrayTy, array, ubounds[i], - builder->getArrayAttr( - {builder->getIntegerAttr(builder->getIndexType(), - static_cast(i)), - builder->getIntegerAttr(builder->getIndexType(), - static_cast(1))})); - exts.push_back(c2); + builder->getArrayAttr({builder->getIntegerAttr( + builder->getIndexType(), + static_cast(i * 2 + 1))})); } builder->create(loc, array, boundArray); mlir::Type boxTy = fir::BoxType::get(boundArrayTy); - mlir::Value shapeOp = builder->genShape(loc, exts); + mlir::Value ext = builder->createIntegerConstant( + loc, indexTy, lbounds.size() * 2); + mlir::Value shapeOp = builder->genShape(loc, {ext}); mlir::Value boundsDesc = builder->create( loc, boxTy, boundArray, shapeOp); Fortran::lower::genPointerAssociateRemapping(*builder, loc, lhs, diff --git a/flang/test/Lower/polymorphic.f90 b/flang/test/Lower/polymorphic.f90 index 37afc5d..3ac8055 100644 --- a/flang/test/Lower/polymorphic.f90 +++ b/flang/test/Lower/polymorphic.f90 @@ -327,32 +327,52 @@ module polymorphic_test subroutine pointer_assign_remap() class(p1), pointer :: a(:) class(p1), pointer :: p(:,:) + class(p1), pointer :: q(:) allocate(a(100)) p(1:10,1:10) => a + q(0:99) => a end subroutine ! CHECK-LABEL: func.func @_QMpolymorphic_testPpointer_assign_remap() { ! CHECK: %[[A:.*]] = fir.alloca !fir.class>>> {bindc_name = "a", uniq_name = "_QMpolymorphic_testFpointer_assign_remapEa"} ! CHECK: %[[P:.*]] = fir.alloca !fir.class>>> {bindc_name = "p", uniq_name = "_QMpolymorphic_testFpointer_assign_remapEp"} +! CHECK: %[[Q:.*]] = fir.alloca !fir.class>>> {bindc_name = "q", uniq_name = "_QMpolymorphic_testFpointer_assign_remapEq"} ! CHECK: %[[C1_0:.*]] = arith.constant 1 : i64 ! CHECK: %[[C10_0:.*]] = arith.constant 10 : i64 ! CHECK: %[[C1_1:.*]] = arith.constant 1 : i64 ! 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<2x2xi64> -! CHECK: %[[ARRAY:.*]] = fir.undefined !fir.array<2x2xi64> -! CHECK: %[[C2:.*]] = arith.constant 2 : index -! 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: %[[BOUND_ARRAY_SHAPE:.*]] = fir.shape %[[C2]], %[[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:.*]] = 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: %[[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: %{{.*}} = fir.call @_FortranAPointerAssociateRemapping(%[[ARG0]], %[[ARG1]], %[[ARG2]], %{{.*}}, %{{.*}}) fastmath : (!fir.ref>, !fir.box, !fir.box, !fir.ref, i32) -> none +! 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: %[[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: %[[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: %{{.*}} = fir.call @_FortranAPointerAssociateRemapping(%[[ARG0]], %[[ARG1]], %[[ARG2]], %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, !fir.box, !fir.box, !fir.ref, i32) -> none end module -- 2.7.4