[flang] Fix bounds array creation for pointer remapping calls
authorValentin Clement <clementval@gmail.com>
Wed, 25 Jan 2023 08:17:27 +0000 (09:17 +0100)
committerValentin Clement <clementval@gmail.com>
Wed, 25 Jan 2023 08:18:05 +0000 (09:18 +0100)
`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
flang/runtime/pointer.cpp
flang/test/Lower/polymorphic.f90

index c8971ea..9c20786 100644 (file)
@@ -2647,25 +2647,31 @@ private:
       assert(lbounds.size() && ubounds.size());
       mlir::Type indexTy = builder->getIndexType();
       mlir::Type boundArrayTy = fir::SequenceType::get(
-          {static_cast<int64_t>(lbounds.size()) * 2}, builder->getI64Type());
+          {static_cast<int64_t>(lbounds.size()), 2}, builder->getI64Type());
       mlir::Value boundArray =
           builder->create<fir::AllocaOp>(loc, boundArrayTy);
       mlir::Value array = builder->create<fir::UndefOp>(loc, boundArrayTy);
       for (unsigned i = 0; i < lbounds.size(); ++i) {
         array = builder->create<fir::InsertValueOp>(
             loc, boundArrayTy, array, lbounds[i],
-            builder->getArrayAttr({builder->getIntegerAttr(
-                builder->getIndexType(), static_cast<int>(i * 2))}));
+            builder->getArrayAttr(
+                {builder->getIntegerAttr(builder->getIndexType(),
+                                         static_cast<int>(i)),
+                 builder->getIntegerAttr(builder->getIndexType(), 0)}));
         array = builder->create<fir::InsertValueOp>(
             loc, boundArrayTy, array, ubounds[i],
-            builder->getArrayAttr({builder->getIntegerAttr(
-                builder->getIndexType(), static_cast<int>(i * 2 + 1))}));
+            builder->getArrayAttr(
+                {builder->getIntegerAttr(builder->getIndexType(),
+                                         static_cast<int>(i)),
+                 builder->getIntegerAttr(builder->getIndexType(), 1)}));
       }
       builder->create<fir::StoreOp>(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<mlir::Value> shapes = {ext, c2};
+      mlir::Value shapeOp = builder->genShape(loc, shapes);
       mlir::Value boundsDesc =
           builder->create<fir::EmboxOp>(loc, boxTy, boundArray, shapeOp);
       Fortran::lower::genPointerAssociateRemapping(*builder, loc, lhs, rhs,
index 06ef736..763348d 100644 (file)
@@ -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<const char>(2 * j),
                       boundElementBytes, terminator),
index cded60f..bcdd4d5 100644 (file)
@@ -400,36 +400,38 @@ module polymorphic_test
 ! CHECK: %[[C10_1:.*]] = arith.constant 10 : i64
 ! CHECK: %[[LOAD_A:.*]] = fir.load %[[A]] : !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>>>
 ! CHECK: %[[REBOX_A:.*]] = fir.rebox %[[LOAD_A]](%{{.*}}) : (!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>>, !fir.shift<1>) -> !fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>
-! 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<!fir.array<4xi64>>
-! 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.array<4xi64>>, !fir.shape<1>) -> !fir.box<!fir.array<4xi64>>
+! 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<!fir.array<2x2xi64>>
+! 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.array<2x2xi64>>, !fir.shape<2>) -> !fir.box<!fir.array<2x2xi64>>
 ! CHECK: %[[ARG0:.*]] = fir.convert %[[P]] : (!fir.ref<!fir.class<!fir.ptr<!fir.array<?x?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>>>) -> !fir.ref<!fir.box<none>>
 ! CHECK: %[[ARG1:.*]] = fir.convert %[[REBOX_A]] : (!fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>) -> !fir.box<none>
-! CHECK: %[[ARG2:.*]] = fir.convert %[[BOXED_BOUND_ARRAY]] : (!fir.box<!fir.array<4xi64>>) -> !fir.box<none>
+! CHECK: %[[ARG2:.*]] = fir.convert %[[BOXED_BOUND_ARRAY]] : (!fir.box<!fir.array<2x2xi64>>) -> !fir.box<none>
 ! CHECK:  %{{.*}} = fir.call @_FortranAPointerAssociateRemapping(%[[ARG0]], %[[ARG1]], %[[ARG2]], %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> none
 
 ! CHECK: %[[C0:.*]] = arith.constant 0 : i64
 ! CHECK: %[[C99:.*]] = arith.constant 99 : i64
 ! CHECK: %[[LOAD_A:.*]] = fir.load %[[A]] : !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>>>
 ! CHECK: %[[REBOX_A:.*]] = fir.rebox %[[LOAD_A]](%{{.*}}) : (!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>>, !fir.shift<1>) -> !fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>
-! 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<!fir.array<2xi64>>
+! 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<!fir.array<1x2xi64>>
+! 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.array<2xi64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi64>>
+! 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.array<1x2xi64>>, !fir.shape<2>) -> !fir.box<!fir.array<1x2xi64>>
 ! CHECK: %[[ARG0:.*]] = fir.convert %[[Q]] : (!fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>>>) -> !fir.ref<!fir.box<none>>
 ! CHECK: %[[ARG1:.*]] = fir.convert %[[REBOX_A]] : (!fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>) -> !fir.box<none>
-! CHECK: %[[ARG2:.*]] = fir.convert %[[BOXED_BOUND_ARRAY]] : (!fir.box<!fir.array<2xi64>>) -> !fir.box<none>
+! CHECK: %[[ARG2:.*]] = fir.convert %[[BOXED_BOUND_ARRAY]] : (!fir.box<!fir.array<1x2xi64>>) -> !fir.box<none>
 ! CHECK: %{{.*}} = fir.call @_FortranAPointerAssociateRemapping(%[[ARG0]], %[[ARG1]], %[[ARG2]], %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> none
 
   subroutine test_elemental_assign()