From 59482586e5927b4e57e275b304e9e17e61af2b9d Mon Sep 17 00:00:00 2001 From: Jean Perier Date: Tue, 6 Sep 2022 14:42:28 +0200 Subject: [PATCH] [flang] Accept assumed shape arrays as SHAPE in C_F_POINTER C_F_POINTER was added in https://reviews.llvm.org/D132303, but the code assumed that SHAPE would always be an explicit shape with compile time constant rank. It can actually be an assumed shape, or an explicit shape with non compile time constant rank. Get the rank from FPTR pointer instead. Differential Revision: https://reviews.llvm.org/D133347 --- flang/lib/Lower/IntrinsicCall.cpp | 19 +++++------ flang/test/Lower/Intrinsics/c_f_pointer.f90 | 53 ++++++++++++++++++++++++----- 2 files changed, 53 insertions(+), 19 deletions(-) diff --git a/flang/lib/Lower/IntrinsicCall.cpp b/flang/lib/Lower/IntrinsicCall.cpp index f431f59..aa86215 100644 --- a/flang/lib/Lower/IntrinsicCall.cpp +++ b/flang/lib/Lower/IntrinsicCall.cpp @@ -2527,19 +2527,16 @@ void IntrinsicLibrary::genCFPointer(llvm::ArrayRef args) { assert(isStaticallyPresent(args[2]) && "FPTR argument must be an array if SHAPE argument exists"); mlir::Value shape = fir::getBase(args[2]); - mlir::Type shapeArrTy = fir::unwrapRefType(shape.getType()); - auto arrayRank = shapeArrTy.cast().getShape()[0]; - assert(arrayRank > 0 && arrayRank <= 15 && - "The rank of array must have been known and in range 1-15"); - for (int i = 0; i < (int)arrayRank; ++i) { - mlir::Value index = - builder.createIntegerConstant(loc, builder.getIntegerType(32), i); + int arrayRank = box.rank(); + mlir::Type shapeElementType = + fir::unwrapSequenceType(fir::unwrapPassByRefType(shape.getType())); + mlir::Type idxType = builder.getIndexType(); + for (int i = 0; i < arrayRank; ++i) { + mlir::Value index = builder.createIntegerConstant(loc, idxType, i); mlir::Value var = builder.create( - loc, builder.getRefType(fir::unwrapSequenceType(shapeArrTy)), shape, - index); + loc, builder.getRefType(shapeElementType), shape, index); mlir::Value load = builder.create(loc, var); - extents.push_back( - builder.createConvert(loc, builder.getIndexType(), load)); + extents.push_back(builder.createConvert(loc, idxType, load)); } } if (box.isCharacter()) { diff --git a/flang/test/Lower/Intrinsics/c_f_pointer.f90 b/flang/test/Lower/Intrinsics/c_f_pointer.f90 index 3de4753..145a306 100644 --- a/flang/test/Lower/Intrinsics/c_f_pointer.f90 +++ b/flang/test/Lower/Intrinsics/c_f_pointer.f90 @@ -30,12 +30,12 @@ end ! CHECK: %[[VAL_66:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_65]] : (!fir.ref>, !fir.field) -> !fir.ref ! CHECK: %[[VAL_67:.*]] = fir.load %[[VAL_66]] : !fir.ref ! CHECK: %[[VAL_68:.*]] = fir.convert %[[VAL_67]] : (i64) -> !fir.ptr> -! CHECK: %[[VAL_69:.*]] = arith.constant 0 : i32 -! CHECK: %[[VAL_70:.*]] = fir.coordinate_of %[[VAL_53:.*]], %[[VAL_69]] : (!fir.heap>, i32) -> !fir.ref +! CHECK: %[[VAL_69:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_70:.*]] = fir.coordinate_of %[[VAL_53:.*]], %[[VAL_69]] : (!fir.heap>, index) -> !fir.ref ! CHECK: %[[VAL_71:.*]] = fir.load %[[VAL_70]] : !fir.ref ! CHECK: %[[VAL_72:.*]] = fir.convert %[[VAL_71]] : (i32) -> index -! CHECK: %[[VAL_73:.*]] = arith.constant 1 : i32 -! CHECK: %[[VAL_74:.*]] = fir.coordinate_of %[[VAL_53]], %[[VAL_73]] : (!fir.heap>, i32) -> !fir.ref +! CHECK: %[[VAL_73:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_74:.*]] = fir.coordinate_of %[[VAL_53]], %[[VAL_73]] : (!fir.heap>, index) -> !fir.ref ! CHECK: %[[VAL_75:.*]] = fir.load %[[VAL_74]] : !fir.ref ! CHECK: %[[VAL_76:.*]] = fir.convert %[[VAL_75]] : (i32) -> index ! CHECK: %[[VAL_77:.*]] = fir.shape %[[VAL_72]], %[[VAL_76]] : (index, index) -> !fir.shape<2> @@ -85,12 +85,12 @@ end ! CHECK: %[[VAL_71:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_70]] : (!fir.ref>, !fir.field) -> !fir.ref ! CHECK: %[[VAL_72:.*]] = fir.load %[[VAL_71]] : !fir.ref ! CHECK: %[[VAL_73:.*]] = fir.convert %[[VAL_72]] : (i64) -> !fir.ptr>> -! CHECK: %[[VAL_74:.*]] = arith.constant 0 : i32 -! CHECK: %[[VAL_75:.*]] = fir.coordinate_of %[[VAL_58:.*]], %[[VAL_74]] : (!fir.heap>, i32) -> !fir.ref +! CHECK: %[[VAL_74:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_75:.*]] = fir.coordinate_of %[[VAL_58:.*]], %[[VAL_74]] : (!fir.heap>, index) -> !fir.ref ! CHECK: %[[VAL_76:.*]] = fir.load %[[VAL_75]] : !fir.ref ! CHECK: %[[VAL_77:.*]] = fir.convert %[[VAL_76]] : (i32) -> index -! CHECK: %[[VAL_78:.*]] = arith.constant 1 : i32 -! CHECK: %[[VAL_79:.*]] = fir.coordinate_of %[[VAL_58]], %[[VAL_78]] : (!fir.heap>, i32) -> !fir.ref +! CHECK: %[[VAL_78:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_79:.*]] = fir.coordinate_of %[[VAL_58]], %[[VAL_78]] : (!fir.heap>, index) -> !fir.ref ! CHECK: %[[VAL_80:.*]] = fir.load %[[VAL_79]] : !fir.ref ! CHECK: %[[VAL_81:.*]] = fir.convert %[[VAL_80]] : (i32) -> index ! CHECK: %[[VAL_82:.*]] = fir.shape %[[VAL_77]], %[[VAL_81]] : (index, index) -> !fir.shape<2> @@ -107,3 +107,40 @@ subroutine test_chararray(cptr, fptr, n) call c_f_pointer(cptr, fptr, [x, y]) end + +! CHECK-LABEL: func.func @_QPdynamic_shape_size( +subroutine dynamic_shape_size(cptr, fptr, shape) + use iso_c_binding + type(c_ptr) :: cptr + real, pointer :: fptr(:, :) + integer :: shape(:) +! CHECK: %[[VAL_7:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_8:.*]] = fir.coordinate_of %[[VAL_2]], %[[VAL_7]] : (!fir.box>, index) -> !fir.ref +! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_8]] : !fir.ref +! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i32) -> index +! CHECK: %[[VAL_11:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_12:.*]] = fir.coordinate_of %[[VAL_2]], %[[VAL_11]] : (!fir.box>, index) -> !fir.ref +! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_12]] : !fir.ref +! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (i32) -> index +! CHECK: %[[VAL_15:.*]] = fir.shape %[[VAL_10]], %[[VAL_14]] : (index, index) -> !fir.shape<2> + call c_f_pointer(cptr, fptr, shape) +end subroutine + +! CHECK-LABEL: func.func @_QPdynamic_shape_size_2( +subroutine dynamic_shape_size_2(cptr, fptr, shape, n) + use iso_c_binding + type(c_ptr) :: cptr + real, pointer :: fptr(:, :) + integer :: n + integer :: shape(n) +! CHECK: %[[VAL_8:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_9:.*]] = fir.coordinate_of %[[VAL_2]], %[[VAL_8]] : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_9]] : !fir.ref +! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (i32) -> index +! CHECK: %[[VAL_12:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_13:.*]] = fir.coordinate_of %[[VAL_2]], %[[VAL_12]] : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[VAL_14:.*]] = fir.load %[[VAL_13]] : !fir.ref +! CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i32) -> index +! CHECK: %[[VAL_16:.*]] = fir.shape %[[VAL_11]], %[[VAL_15]] : (index, index) -> !fir.shape<2> + call c_f_pointer(cptr, fptr, shape) +end subroutine -- 2.7.4