[flang-commits] [flang] 109f9a2 - [flang] Support lowering of intrinsic module procedure C_F_POINTER
Peixin Qiao via flang-commits
flang-commits at lists.llvm.org
Mon Sep 5 17:16:02 PDT 2022
Author: Peixin Qiao
Date: 2022-09-06T08:15:01+08:00
New Revision: 109f9a291850a8e82f5026f68a382222a235c4f3
URL: https://github.com/llvm/llvm-project/commit/109f9a291850a8e82f5026f68a382222a235c4f3
DIFF: https://github.com/llvm/llvm-project/commit/109f9a291850a8e82f5026f68a382222a235c4f3.diff
LOG: [flang] Support lowering of intrinsic module procedure C_F_POINTER
As Fortran 2018 18.2.3.3, the intrinsic module procedure
C_F_POINTER(CPTR, FPTR [, SHAPE]) associates a data pointer with the
target of a C pointer and specify its shape. CPTR shall be a scalar of
type C_PTR, and its value is the C address or the result of a reference
to C_LOC. FPTR is one pointer, either scalar or array. SHAPE is a
rank-one integer array, and it shall be present if and only if FPTR is
an array.
C_PTR is the derived type with only one component of integer 64, and the
integer 64 component value is the address. Build the right "source"
fir::ExtendedValue based on the address and shape, and use
associateMutableBox to associate the pointer with the target of the C
pointer.
Refactor the getting the address of C_PTR to reuse the code.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D132303
Added:
flang/test/Lower/Intrinsics/c_f_pointer.f90
Modified:
flang/include/flang/Optimizer/Builder/FIRBuilder.h
flang/lib/Lower/Bridge.cpp
flang/lib/Lower/ConvertExpr.cpp
flang/lib/Lower/IntrinsicCall.cpp
flang/lib/Optimizer/Builder/FIRBuilder.cpp
flang/test/Lower/Intrinsics/c_funloc.f90
flang/test/Lower/Intrinsics/c_loc.f90
Removed:
################################################################################
diff --git a/flang/include/flang/Optimizer/Builder/FIRBuilder.h b/flang/include/flang/Optimizer/Builder/FIRBuilder.h
index 3a1711bbf3d7..653b6ebe6f99 100644
--- a/flang/include/flang/Optimizer/Builder/FIRBuilder.h
+++ b/flang/include/flang/Optimizer/Builder/FIRBuilder.h
@@ -551,6 +551,12 @@ getExtentFromTriplet(mlir::Value lb, mlir::Value ub, mlir::Value stride);
mlir::Value genMaxWithZero(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value value);
+/// The type(C_PTR/C_FUNPTR) is defined as the derived type with only one
+/// component of integer 64, and the component is the C address. Get the C
+/// address.
+mlir::Value genCPtrOrCFunptrAddr(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value cPtr, mlir::Type ty);
+
} // namespace fir::factory
#endif // FORTRAN_OPTIMIZER_BUILDER_FIRBUILDER_H
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 7ec4a219ff60..114ef4e37c25 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -2688,20 +2688,12 @@ class FirConverter : public Fortran::lower::AbstractConverter {
void mapCPtrArgByValue(const Fortran::semantics::Symbol &sym,
mlir::Value val) {
mlir::Type symTy = Fortran::lower::translateSymbolToFIRType(*this, sym);
- assert(symTy.isa<fir::RecordType>());
- auto resTy = symTy.dyn_cast<fir::RecordType>();
- assert(resTy.getTypeList().size() == 1);
- auto fieldName = resTy.getTypeList()[0].first;
- auto fieldTy = resTy.getTypeList()[0].second;
mlir::Location loc = toLocation();
mlir::Value res = builder->create<fir::AllocaOp>(loc, symTy);
- auto fieldIndexType = fir::FieldType::get(symTy.getContext());
- mlir::Value field = builder->create<fir::FieldIndexOp>(
- loc, fieldIndexType, fieldName, resTy,
- /*typeParams=*/mlir::ValueRange{});
- mlir::Value resAddr = builder->create<fir::CoordinateOp>(
- loc, builder->getRefType(fieldTy), res, field);
- mlir::Value argAddrVal = builder->createConvert(loc, fieldTy, val);
+ mlir::Value resAddr =
+ fir::factory::genCPtrOrCFunptrAddr(*builder, loc, res, symTy);
+ mlir::Value argAddrVal =
+ builder->createConvert(loc, fir::unwrapRefType(resAddr.getType()), val);
builder->create<fir::StoreOp>(loc, argAddrVal, resAddr);
addSymbol(sym, res);
}
diff --git a/flang/lib/Lower/ConvertExpr.cpp b/flang/lib/Lower/ConvertExpr.cpp
index 57e8d81ac713..209ebf15451b 100644
--- a/flang/lib/Lower/ConvertExpr.cpp
+++ b/flang/lib/Lower/ConvertExpr.cpp
@@ -2484,21 +2484,12 @@ class ScalarExprLowering {
static mlir::Value
genRecordCPtrValueArg(Fortran::lower::AbstractConverter &converter,
mlir::Value rec, mlir::Type ty) {
- assert(fir::isa_derived(ty));
- auto recTy = ty.dyn_cast<fir::RecordType>();
- assert(recTy.getTypeList().size() == 1);
- auto fieldName = recTy.getTypeList()[0].first;
- mlir::Type fieldTy = recTy.getTypeList()[0].second;
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
mlir::Location loc = converter.getCurrentLocation();
- auto fieldIndexType = fir::FieldType::get(ty.getContext());
- mlir::Value field =
- builder.create<fir::FieldIndexOp>(loc, fieldIndexType, fieldName, recTy,
- /*typeParams=*/mlir::ValueRange{});
- mlir::Value cAddr = builder.create<fir::CoordinateOp>(
- loc, builder.getRefType(fieldTy), rec, field);
- mlir::Value val = builder.create<fir::LoadOp>(loc, cAddr);
- return builder.createConvert(loc, builder.getRefType(fieldTy), val);
+ mlir::Value cAddr =
+ fir::factory::genCPtrOrCFunptrAddr(builder, loc, rec, ty);
+ mlir::Value cVal = builder.create<fir::LoadOp>(loc, cAddr);
+ return builder.createConvert(loc, cAddr.getType(), cVal);
}
/// Given a call site for which the arguments were already lowered, generate
diff --git a/flang/lib/Lower/IntrinsicCall.cpp b/flang/lib/Lower/IntrinsicCall.cpp
index 4335cb7a7297..f431f59370f8 100644
--- a/flang/lib/Lower/IntrinsicCall.cpp
+++ b/flang/lib/Lower/IntrinsicCall.cpp
@@ -480,6 +480,7 @@ struct IntrinsicLibrary {
fir::ExtendedValue genCount(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
void genCpuTime(llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genCshift(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
+ void genCFPointer(llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genCFunLoc(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genCLoc(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
void genDateAndTime(llvm::ArrayRef<fir::ExtendedValue>);
@@ -726,6 +727,12 @@ static constexpr IntrinsicHandler handlers[]{
{"ble", &I::genBitwiseCompare<mlir::arith::CmpIPredicate::ule>},
{"blt", &I::genBitwiseCompare<mlir::arith::CmpIPredicate::ult>},
{"btest", &I::genBtest},
+ {"c_f_pointer",
+ &I::genCFPointer,
+ {{{"cptr", asValue},
+ {"fptr", asInquired},
+ {"shape", asAddr, handleDynamicOptional}}},
+ /*isElemental=*/false},
{"c_funloc", &I::genCFunLoc, {{{"x", asBox}}}, /*isElemental=*/false},
{"c_loc", &I::genCLoc, {{{"x", asBox}}}, /*isElemental=*/false},
{"ceiling", &I::genCeiling},
@@ -2474,12 +2481,10 @@ static fir::ExtendedValue
genCLocOrCFunLoc(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Type resultType, llvm::ArrayRef<fir::ExtendedValue> args,
bool isFunc = false) {
- assert(args.size() == 1 && resultType.isa<fir::RecordType>());
- auto resTy = resultType.dyn_cast<fir::RecordType>();
- assert(resTy.getTypeList().size() == 1);
- auto fieldName = resTy.getTypeList()[0].first;
- auto fieldTy = resTy.getTypeList()[0].second;
+ assert(args.size() == 1);
mlir::Value res = builder.create<fir::AllocaOp>(loc, resultType);
+ mlir::Value resAddr =
+ fir::factory::genCPtrOrCFunptrAddr(builder, loc, res, resultType);
mlir::Value argAddr;
if (isFunc) {
mlir::Value argValue = fir::getBase(args[0]);
@@ -2493,16 +2498,67 @@ genCLocOrCFunLoc(fir::FirOpBuilder &builder, mlir::Location loc,
argAddr = builder.create<fir::BoxAddrOp>(loc, box->getMemTy(),
fir::getBase(*box));
}
- mlir::Value argAddrVal = builder.createConvert(loc, fieldTy, argAddr);
- auto fieldIndexType = fir::FieldType::get(resultType.getContext());
- mlir::Value field = builder.create<fir::FieldIndexOp>(
- loc, fieldIndexType, fieldName, resTy, /*typeParams=*/mlir::ValueRange{});
- mlir::Value resAddr = builder.create<fir::CoordinateOp>(
- loc, builder.getRefType(fieldTy), res, field);
+ mlir::Value argAddrVal = builder.createConvert(
+ loc, fir::unwrapRefType(resAddr.getType()), argAddr);
builder.create<fir::StoreOp>(loc, argAddrVal, resAddr);
return res;
}
+// C_F_POINTER
+void IntrinsicLibrary::genCFPointer(llvm::ArrayRef<fir::ExtendedValue> args) {
+ assert(args.size() == 3);
+ // Handle CPTR argument
+ // Get the value of the C address or the result of a reference to C_LOC.
+ mlir::Value cPtr = fir::getBase(args[0]);
+ mlir::Type cPtrTy = fir::unwrapRefType(cPtr.getType());
+ mlir::Value cPtrAddr =
+ fir::factory::genCPtrOrCFunptrAddr(builder, loc, cPtr, cPtrTy);
+ mlir::Value cPtrAddrVal = builder.create<fir::LoadOp>(loc, cPtrAddr);
+
+ // Handle FPTR argument
+ const auto *fPtr = args[1].getBoxOf<fir::MutableBoxValue>();
+ assert(fPtr && "FPTR must be a pointer");
+
+ auto getCPtrExtVal = [&](fir::MutableBoxValue box) -> fir::ExtendedValue {
+ mlir::Value addr =
+ builder.createConvert(loc, fPtr->getMemTy(), cPtrAddrVal);
+ mlir::SmallVector<mlir::Value> extents;
+ if (box.hasRank()) {
+ 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<fir::SequenceType>().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);
+ mlir::Value var = builder.create<fir::CoordinateOp>(
+ loc, builder.getRefType(fir::unwrapSequenceType(shapeArrTy)), shape,
+ index);
+ mlir::Value load = builder.create<fir::LoadOp>(loc, var);
+ extents.push_back(
+ builder.createConvert(loc, builder.getIndexType(), load));
+ }
+ }
+ if (box.isCharacter()) {
+ mlir::Value len = box.nonDeferredLenParams()[0];
+ if (box.hasRank())
+ return fir::CharArrayBoxValue{addr, len, extents};
+ return fir::CharBoxValue{addr, len};
+ }
+ if (box.isDerivedWithLenParameters())
+ TODO(loc, "get length parameters of derived type");
+ if (box.hasRank())
+ return fir::ArrayBoxValue{addr, extents};
+ return addr;
+ };
+
+ fir::factory::associateMutableBox(builder, loc, *fPtr, getCPtrExtVal(*fPtr),
+ /*lbounds=*/mlir::ValueRange{});
+}
+
// C_FUNLOC
fir::ExtendedValue
IntrinsicLibrary::genCFunLoc(mlir::Type resultType,
diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp
index 6c3d4bdd7ce9..446e3b78a443 100644
--- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp
+++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp
@@ -1268,3 +1268,20 @@ mlir::Value fir::factory::genMaxWithZero(fir::FirOpBuilder &builder,
return builder.create<mlir::arith::SelectOp>(loc, valueIsGreater, value,
zero);
}
+
+mlir::Value fir::factory::genCPtrOrCFunptrAddr(fir::FirOpBuilder &builder,
+ mlir::Location loc,
+ mlir::Value cPtr,
+ mlir::Type ty) {
+ assert(ty.isa<fir::RecordType>());
+ auto recTy = ty.dyn_cast<fir::RecordType>();
+ assert(recTy.getTypeList().size() == 1);
+ auto fieldName = recTy.getTypeList()[0].first;
+ mlir::Type fieldTy = recTy.getTypeList()[0].second;
+ auto fieldIndexType = fir::FieldType::get(ty.getContext());
+ mlir::Value field =
+ builder.create<fir::FieldIndexOp>(loc, fieldIndexType, fieldName, recTy,
+ /*typeParams=*/mlir::ValueRange{});
+ return builder.create<fir::CoordinateOp>(loc, builder.getRefType(fieldTy),
+ cPtr, field);
+}
diff --git a/flang/test/Lower/Intrinsics/c_f_pointer.f90 b/flang/test/Lower/Intrinsics/c_f_pointer.f90
new file mode 100644
index 000000000000..3de47534af98
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/c_f_pointer.f90
@@ -0,0 +1,109 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
+
+! Test intrinsic module procedure c_f_pointer
+
+! CHECK-LABEL: func.func @_QPtest_scalar(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>> {fir.bindc_name = "cptr"},
+! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.ptr<f32>>> {fir.bindc_name = "fptr"}) {
+! CHECK: %[[VAL_2:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
+! CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_2]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
+! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_3]] : !fir.ref<i64>
+! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i64) -> !fir.ptr<f32>
+! CHECK: %[[VAL_6:.*]] = fir.embox %[[VAL_5]] : (!fir.ptr<f32>) -> !fir.box<!fir.ptr<f32>>
+! CHECK: fir.store %[[VAL_6]] to %[[VAL_1]] : !fir.ref<!fir.box<!fir.ptr<f32>>>
+! CHECK: return
+! CHECK: }
+
+subroutine test_scalar(cptr, fptr)
+ use iso_c_binding
+ real, pointer :: fptr
+ type(c_ptr) :: cptr
+
+ call c_f_pointer(cptr, fptr)
+end
+
+! CHECK-LABEL: func.func @_QPtest_array(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>> {fir.bindc_name = "cptr"},
+! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x?xf32>>>> {fir.bindc_name = "fptr"}) {
+! CHECK: %[[VAL_65:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
+! CHECK: %[[VAL_66:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_65]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
+! CHECK: %[[VAL_67:.*]] = fir.load %[[VAL_66]] : !fir.ref<i64>
+! CHECK: %[[VAL_68:.*]] = fir.convert %[[VAL_67]] : (i64) -> !fir.ptr<!fir.array<?x?xf32>>
+! CHECK: %[[VAL_69:.*]] = arith.constant 0 : i32
+! CHECK: %[[VAL_70:.*]] = fir.coordinate_of %[[VAL_53:.*]], %[[VAL_69]] : (!fir.heap<!fir.array<2xi32>>, i32) -> !fir.ref<i32>
+! CHECK: %[[VAL_71:.*]] = fir.load %[[VAL_70]] : !fir.ref<i32>
+! 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<!fir.array<2xi32>>, i32) -> !fir.ref<i32>
+! CHECK: %[[VAL_75:.*]] = fir.load %[[VAL_74]] : !fir.ref<i32>
+! CHECK: %[[VAL_76:.*]] = fir.convert %[[VAL_75]] : (i32) -> index
+! CHECK: %[[VAL_77:.*]] = fir.shape %[[VAL_72]], %[[VAL_76]] : (index, index) -> !fir.shape<2>
+! CHECK: %[[VAL_78:.*]] = fir.embox %[[VAL_68]](%[[VAL_77]]) : (!fir.ptr<!fir.array<?x?xf32>>, !fir.shape<2>) -> !fir.box<!fir.ptr<!fir.array<?x?xf32>>>
+! CHECK: fir.store %[[VAL_78]] to %[[VAL_1]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x?xf32>>>>
+! CHECK: return
+! CHECK: }
+
+subroutine test_array(cptr, fptr)
+ use iso_c_binding
+ real, pointer :: fptr(:,:)
+ type(c_ptr) :: cptr
+ integer :: x = 3, y = 4
+
+ call c_f_pointer(cptr, fptr, [x, y])
+end
+
+! CHECK-LABEL: func.func @_QPtest_char(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>> {fir.bindc_name = "cptr"},
+! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.char<1,10>>>> {fir.bindc_name = "fptr"}) {
+! CHECK: %[[VAL_2:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
+! CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_2]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
+! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_3]] : !fir.ref<i64>
+! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i64) -> !fir.ptr<!fir.char<1,10>>
+! CHECK: %[[VAL_6:.*]] = fir.embox %[[VAL_5]] : (!fir.ptr<!fir.char<1,10>>) -> !fir.box<!fir.ptr<!fir.char<1,10>>>
+! CHECK: fir.store %[[VAL_6]] to %[[VAL_1]] : !fir.ref<!fir.box<!fir.ptr<!fir.char<1,10>>>>
+! CHECK: return
+! CHECK: }
+
+subroutine test_char(cptr, fptr)
+ use iso_c_binding
+ character(10), pointer :: fptr
+ type(c_ptr) :: cptr
+
+ call c_f_pointer(cptr, fptr)
+end
+
+! CHECK-LABEL: func.func @_QPtest_chararray(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>> {fir.bindc_name = "cptr"},
+! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x?x!fir.char<1,?>>>>> {fir.bindc_name = "fptr"},
+! CHECK-SAME: %[[VAL_2:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
+! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32>
+! CHECK: %[[VAL_8:.*]] = arith.constant 0 : i32
+! CHECK: %[[VAL_9:.*]] = arith.cmpi sgt, %[[VAL_7]], %[[VAL_8]] : i32
+! CHECK: %[[VAL_10:.*]] = arith.select %[[VAL_9]], %[[VAL_7]], %[[VAL_8]] : i32
+! CHECK: %[[VAL_70:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
+! CHECK: %[[VAL_71:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_70]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
+! CHECK: %[[VAL_72:.*]] = fir.load %[[VAL_71]] : !fir.ref<i64>
+! CHECK: %[[VAL_73:.*]] = fir.convert %[[VAL_72]] : (i64) -> !fir.ptr<!fir.array<?x?x!fir.char<1,?>>>
+! CHECK: %[[VAL_74:.*]] = arith.constant 0 : i32
+! CHECK: %[[VAL_75:.*]] = fir.coordinate_of %[[VAL_58:.*]], %[[VAL_74]] : (!fir.heap<!fir.array<2xi32>>, i32) -> !fir.ref<i32>
+! CHECK: %[[VAL_76:.*]] = fir.load %[[VAL_75]] : !fir.ref<i32>
+! 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<!fir.array<2xi32>>, i32) -> !fir.ref<i32>
+! CHECK: %[[VAL_80:.*]] = fir.load %[[VAL_79]] : !fir.ref<i32>
+! CHECK: %[[VAL_81:.*]] = fir.convert %[[VAL_80]] : (i32) -> index
+! CHECK: %[[VAL_82:.*]] = fir.shape %[[VAL_77]], %[[VAL_81]] : (index, index) -> !fir.shape<2>
+! CHECK: %[[VAL_83:.*]] = fir.embox %[[VAL_73]](%[[VAL_82]]) typeparams %[[VAL_10]] : (!fir.ptr<!fir.array<?x?x!fir.char<1,?>>>, !fir.shape<2>, i32) -> !fir.box<!fir.ptr<!fir.array<?x?x!fir.char<1,?>>>>
+! CHECK: fir.store %[[VAL_83]] to %[[VAL_1]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x?x!fir.char<1,?>>>>>
+! CHECK: return
+! CHECK: }
+
+subroutine test_chararray(cptr, fptr, n)
+ use iso_c_binding
+ character(n), pointer :: fptr(:,:)
+ type(c_ptr) :: cptr
+ integer :: x = 3, y = 4
+
+ call c_f_pointer(cptr, fptr, [x, y])
+end
diff --git a/flang/test/Lower/Intrinsics/c_funloc.f90 b/flang/test/Lower/Intrinsics/c_funloc.f90
index 7faaaef00b0d..1f7e54e24b77 100644
--- a/flang/test/Lower/Intrinsics/c_funloc.f90
+++ b/flang/test/Lower/Intrinsics/c_funloc.f90
@@ -7,10 +7,10 @@
! CHECK: %[[VAL_1:.*]] = fir.address_of(@_QPfoo) : (!fir.ref<i32>) -> ()
! CHECK: %[[VAL_2:.*]] = fir.emboxproc %[[VAL_1]] : ((!fir.ref<i32>) -> ()) -> !fir.boxproc<(!fir.ref<i32>) -> ()>
! CHECK: %[[VAL_3:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>
-! CHECK: %[[VAL_4:.*]] = fir.box_addr %[[VAL_2]] : (!fir.boxproc<(!fir.ref<i32>) -> ()>) -> ((!fir.ref<i32>) -> ())
-! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : ((!fir.ref<i32>) -> ()) -> i64
-! CHECK: %[[VAL_6:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>
-! CHECK: %[[VAL_7:.*]] = fir.coordinate_of %[[VAL_3]], %[[VAL_6]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
+! CHECK-DAG: %[[VAL_4:.*]] = fir.box_addr %[[VAL_2]] : (!fir.boxproc<(!fir.ref<i32>) -> ()>) -> ((!fir.ref<i32>) -> ())
+! CHECK-DAG: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : ((!fir.ref<i32>) -> ()) -> i64
+! CHECK-DAG: %[[VAL_6:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>
+! CHECK-DAG: %[[VAL_7:.*]] = fir.coordinate_of %[[VAL_3]], %[[VAL_6]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
! CHECK: fir.store %[[VAL_5]] to %[[VAL_7]] : !fir.ref<i64>
subroutine test()
diff --git a/flang/test/Lower/Intrinsics/c_loc.f90 b/flang/test/Lower/Intrinsics/c_loc.f90
index 77bbc5364739..34b0fb2fd833 100644
--- a/flang/test/Lower/Intrinsics/c_loc.f90
+++ b/flang/test/Lower/Intrinsics/c_loc.f90
@@ -8,10 +8,10 @@
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> {bindc_name = "ptr", uniq_name = "_QFc_loc_scalarEptr"}
! CHECK: %[[VAL_2:.*]] = fir.embox %[[VAL_0]] : (!fir.ref<i32>) -> !fir.box<i32>
! CHECK: %[[VAL_3:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
-! CHECK: %[[VAL_4:.*]] = fir.box_addr %[[VAL_2]] : (!fir.box<i32>) -> !fir.ref<i32>
-! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (!fir.ref<i32>) -> i64
-! CHECK: %[[VAL_6:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
-! CHECK: %[[VAL_7:.*]] = fir.coordinate_of %[[VAL_3]], %[[VAL_6]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
+! CHECK-DAG: %[[VAL_4:.*]] = fir.box_addr %[[VAL_2]] : (!fir.box<i32>) -> !fir.ref<i32>
+! CHECK-DAG: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (!fir.ref<i32>) -> i64
+! CHECK-DAG: %[[VAL_6:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
+! CHECK-DAG: %[[VAL_7:.*]] = fir.coordinate_of %[[VAL_3]], %[[VAL_6]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
! CHECK: fir.store %[[VAL_5]] to %[[VAL_7]] : !fir.ref<i64>
! CHECK: }
@@ -27,10 +27,10 @@ subroutine c_loc_scalar()
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> {bindc_name = "ptr", uniq_name = "_QFc_loc_charEptr"}
! CHECK: %[[VAL_2:.*]] = fir.embox %[[VAL_0]] : (!fir.ref<!fir.char<1,5>>) -> !fir.box<!fir.char<1,5>>
! CHECK: %[[VAL_3:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
-! CHECK: %[[VAL_4:.*]] = fir.box_addr %[[VAL_2]] : (!fir.box<!fir.char<1,5>>) -> !fir.ref<!fir.char<1,5>>
-! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (!fir.ref<!fir.char<1,5>>) -> i64
-! CHECK: %[[VAL_6:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
-! CHECK: %[[VAL_7:.*]] = fir.coordinate_of %[[VAL_3]], %[[VAL_6]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
+! CHECK-DAG: %[[VAL_4:.*]] = fir.box_addr %[[VAL_2]] : (!fir.box<!fir.char<1,5>>) -> !fir.ref<!fir.char<1,5>>
+! CHECK-DAG: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (!fir.ref<!fir.char<1,5>>) -> i64
+! CHECK-DAG: %[[VAL_6:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
+! CHECK-DAG: %[[VAL_7:.*]] = fir.coordinate_of %[[VAL_3]], %[[VAL_6]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
! CHECK: fir.store %[[VAL_5]] to %[[VAL_7]] : !fir.ref<i64>
! CHECK: }
@@ -60,10 +60,10 @@ subroutine c_loc_char()
! CHECK: %[[VAL_15:.*]] = arith.select %[[VAL_14]], %[[VAL_13]], %[[VAL_12]] : index
! CHECK: %[[VAL_16:.*]] = fir.embox %[[VAL_10]] typeparams %[[VAL_15]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.box<!fir.char<1,?>>
! CHECK: %[[VAL_17:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
-! CHECK: %[[VAL_18:.*]] = fir.box_addr %[[VAL_16]] : (!fir.box<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,?>>
-! CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_18]] : (!fir.ref<!fir.char<1,?>>) -> i64
-! CHECK: %[[VAL_20:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
-! CHECK: %[[VAL_21:.*]] = fir.coordinate_of %[[VAL_17]], %[[VAL_20]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
+! CHECK-DAG: %[[VAL_18:.*]] = fir.box_addr %[[VAL_16]] : (!fir.box<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,?>>
+! CHECK-DAG: %[[VAL_19:.*]] = fir.convert %[[VAL_18]] : (!fir.ref<!fir.char<1,?>>) -> i64
+! CHECK-DAG: %[[VAL_20:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
+! CHECK-DAG: %[[VAL_21:.*]] = fir.coordinate_of %[[VAL_17]], %[[VAL_20]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
! CHECK: fir.store %[[VAL_19]] to %[[VAL_21]] : !fir.ref<i64>
! CHECK: }
@@ -81,10 +81,10 @@ subroutine c_loc_substring()
! CHECK: %[[VAL_3:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1>
! CHECK: %[[VAL_4:.*]] = fir.embox %[[VAL_0]](%[[VAL_3]]) : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<10xi32>>
! CHECK: %[[VAL_5:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
-! CHECK: %[[VAL_6:.*]] = fir.box_addr %[[VAL_4]] : (!fir.box<!fir.array<10xi32>>) -> !fir.ref<!fir.array<10xi32>>
-! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (!fir.ref<!fir.array<10xi32>>) -> i64
-! CHECK: %[[VAL_8:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
-! CHECK: %[[VAL_9:.*]] = fir.coordinate_of %[[VAL_5]], %[[VAL_8]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
+! CHECK-DAG: %[[VAL_6:.*]] = fir.box_addr %[[VAL_4]] : (!fir.box<!fir.array<10xi32>>) -> !fir.ref<!fir.array<10xi32>>
+! CHECK-DAG: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (!fir.ref<!fir.array<10xi32>>) -> i64
+! CHECK-DAG: %[[VAL_8:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
+! CHECK-DAG: %[[VAL_9:.*]] = fir.coordinate_of %[[VAL_5]], %[[VAL_8]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
! CHECK: fir.store %[[VAL_7]] to %[[VAL_9]] : !fir.ref<i64>
! CHECK: }
@@ -102,10 +102,10 @@ subroutine c_loc_array
! CHECK: %[[VAL_3:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1>
! CHECK: %[[VAL_4:.*]] = fir.embox %[[VAL_0]](%[[VAL_3]]) : (!fir.ref<!fir.array<2x!fir.char<1,5>>>, !fir.shape<1>) -> !fir.box<!fir.array<2x!fir.char<1,5>>>
! CHECK: %[[VAL_5:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
-! CHECK: %[[VAL_6:.*]] = fir.box_addr %[[VAL_4]] : (!fir.box<!fir.array<2x!fir.char<1,5>>>) -> !fir.ref<!fir.array<2x!fir.char<1,5>>>
-! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (!fir.ref<!fir.array<2x!fir.char<1,5>>>) -> i64
-! CHECK: %[[VAL_8:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
-! CHECK: %[[VAL_9:.*]] = fir.coordinate_of %[[VAL_5]], %[[VAL_8]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
+! CHECK-DAG: %[[VAL_6:.*]] = fir.box_addr %[[VAL_4]] : (!fir.box<!fir.array<2x!fir.char<1,5>>>) -> !fir.ref<!fir.array<2x!fir.char<1,5>>>
+! CHECK-DAG: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (!fir.ref<!fir.array<2x!fir.char<1,5>>>) -> i64
+! CHECK-DAG: %[[VAL_8:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
+! CHECK-DAG: %[[VAL_9:.*]] = fir.coordinate_of %[[VAL_5]], %[[VAL_8]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
! CHECK: fir.store %[[VAL_7]] to %[[VAL_9]] : !fir.ref<i64>
! CHECK: }
@@ -125,10 +125,10 @@ subroutine c_loc_chararray()
! CHECK: %[[VAL_5:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_4]] : (!fir.ref<!fir.array<10xi32>>, i64) -> !fir.ref<i32>
! CHECK: %[[VAL_6:.*]] = fir.embox %[[VAL_5]] : (!fir.ref<i32>) -> !fir.box<i32>
! CHECK: %[[VAL_7:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
-! CHECK: %[[VAL_8:.*]] = fir.box_addr %[[VAL_6]] : (!fir.box<i32>) -> !fir.ref<i32>
-! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_8]] : (!fir.ref<i32>) -> i64
-! CHECK: %[[VAL_10:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
-! CHECK: %[[VAL_11:.*]] = fir.coordinate_of %[[VAL_7]], %[[VAL_10]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
+! CHECK-DAG: %[[VAL_8:.*]] = fir.box_addr %[[VAL_6]] : (!fir.box<i32>) -> !fir.ref<i32>
+! CHECK-DAG: %[[VAL_9:.*]] = fir.convert %[[VAL_8]] : (!fir.ref<i32>) -> i64
+! CHECK-DAG: %[[VAL_10:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
+! CHECK-DAG: %[[VAL_11:.*]] = fir.coordinate_of %[[VAL_7]], %[[VAL_10]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
! CHECK: fir.store %[[VAL_9]] to %[[VAL_11]] : !fir.ref<i64>
! CHECK: }
@@ -156,10 +156,10 @@ subroutine c_loc_arrayelement()
! CHECK: %[[VAL_13:.*]] = fir.slice %[[VAL_7]], %[[VAL_11]], %[[VAL_9]] : (index, index, index) -> !fir.slice<1>
! CHECK: %[[VAL_14:.*]] = fir.embox %[[VAL_0]](%[[VAL_12]]) {{\[}}%[[VAL_13]]] : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<?xi32>>
! CHECK: %[[VAL_15:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
-! CHECK: %[[VAL_16:.*]] = fir.box_addr %[[VAL_14]] : (!fir.box<!fir.array<?xi32>>) -> !fir.ref<!fir.array<?xi32>>
-! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (!fir.ref<!fir.array<?xi32>>) -> i64
-! CHECK: %[[VAL_18:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
-! CHECK: %[[VAL_19:.*]] = fir.coordinate_of %[[VAL_15]], %[[VAL_18]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
+! CHECK-DAG: %[[VAL_16:.*]] = fir.box_addr %[[VAL_14]] : (!fir.box<!fir.array<?xi32>>) -> !fir.ref<!fir.array<?xi32>>
+! CHECK-DAG: %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (!fir.ref<!fir.array<?xi32>>) -> i64
+! CHECK-DAG: %[[VAL_18:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
+! CHECK-DAG: %[[VAL_19:.*]] = fir.coordinate_of %[[VAL_15]], %[[VAL_18]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
! CHECK: fir.store %[[VAL_17]] to %[[VAL_19]] : !fir.ref<i64>
! CHECK: }
@@ -186,10 +186,10 @@ subroutine c_loc_arraysection()
! CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.ptr<i32>>
! CHECK: %[[VAL_9:.*]] = fir.embox %[[VAL_8]] : (!fir.ptr<i32>) -> !fir.box<i32>
! CHECK: %[[VAL_10:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
-! CHECK: %[[VAL_11:.*]] = fir.box_addr %[[VAL_9]] : (!fir.box<i32>) -> !fir.ref<i32>
-! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (!fir.ref<i32>) -> i64
-! CHECK: %[[VAL_13:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
-! CHECK: %[[VAL_14:.*]] = fir.coordinate_of %[[VAL_10]], %[[VAL_13]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
+! CHECK-DAG: %[[VAL_11:.*]] = fir.box_addr %[[VAL_9]] : (!fir.box<i32>) -> !fir.ref<i32>
+! CHECK-DAG: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (!fir.ref<i32>) -> i64
+! CHECK-DAG: %[[VAL_13:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
+! CHECK-DAG: %[[VAL_14:.*]] = fir.coordinate_of %[[VAL_10]], %[[VAL_13]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
! CHECK: fir.store %[[VAL_12]] to %[[VAL_14]] : !fir.ref<i64>
! CHECK: }
@@ -208,10 +208,10 @@ subroutine c_loc_non_save_pointer_scalar()
! CHECK: %[[VAL_8:.*]] = fir.box_addr %[[VAL_7]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
! CHECK: %[[VAL_9:.*]] = fir.embox %[[VAL_8:.*]] : (!fir.ptr<i32>) -> !fir.box<i32>
! CHECK: %[[VAL_10:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
-! CHECK: %[[VAL_11:.*]] = fir.box_addr %[[VAL_9]] : (!fir.box<i32>) -> !fir.ref<i32>
-! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (!fir.ref<i32>) -> i64
-! CHECK: %[[VAL_13:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
-! CHECK: %[[VAL_14:.*]] = fir.coordinate_of %[[VAL_10]], %[[VAL_13]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
+! CHECK-DAG: %[[VAL_11:.*]] = fir.box_addr %[[VAL_9]] : (!fir.box<i32>) -> !fir.ref<i32>
+! CHECK-DAG: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (!fir.ref<i32>) -> i64
+! CHECK-DAG: %[[VAL_13:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
+! CHECK-DAG: %[[VAL_14:.*]] = fir.coordinate_of %[[VAL_10]], %[[VAL_13]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
! CHECK: fir.store %[[VAL_12]] to %[[VAL_14]] : !fir.ref<i64>
! CHECK: }
@@ -228,10 +228,10 @@ subroutine c_loc_save_pointer_scalar()
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QFc_loc_derived_typeTt{i:i32}> {bindc_name = "tt", fir.target, uniq_name = "_QFc_loc_derived_typeEtt"}
! CHECK: %[[VAL_8:.*]] = fir.embox %[[VAL_1]] : (!fir.ref<!fir.type<_QFc_loc_derived_typeTt{i:i32}>>) -> !fir.box<!fir.type<_QFc_loc_derived_typeTt{i:i32}>>
! CHECK: %[[VAL_9:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
-! CHECK: %[[VAL_10:.*]] = fir.box_addr %[[VAL_8:.*]] : (!fir.box<!fir.type<_QFc_loc_derived_typeTt{i:i32}>>) -> !fir.ref<!fir.type<_QFc_loc_derived_typeTt{i:i32}>>
-! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (!fir.ref<!fir.type<_QFc_loc_derived_typeTt{i:i32}>>) -> i64
-! CHECK: %[[VAL_12:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
-! CHECK: %[[VAL_13:.*]] = fir.coordinate_of %[[VAL_9]], %[[VAL_12]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
+! CHECK-DAG: %[[VAL_10:.*]] = fir.box_addr %[[VAL_8:.*]] : (!fir.box<!fir.type<_QFc_loc_derived_typeTt{i:i32}>>) -> !fir.ref<!fir.type<_QFc_loc_derived_typeTt{i:i32}>>
+! CHECK-DAG: %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (!fir.ref<!fir.type<_QFc_loc_derived_typeTt{i:i32}>>) -> i64
+! CHECK-DAG: %[[VAL_12:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
+! CHECK-DAG: %[[VAL_13:.*]] = fir.coordinate_of %[[VAL_9]], %[[VAL_12]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
! CHECK: fir.store %[[VAL_11]] to %[[VAL_13]] : !fir.ref<i64>
! CHECK: }
@@ -249,10 +249,10 @@ subroutine c_loc_derived_type
! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?xi32>>> {bindc_name = "a", uniq_name = "_QFc_loc_pointer_arrayEa"}
! CHECK: %[[VAL_30:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
! CHECK: %[[VAL_31:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
-! CHECK: %[[VAL_32:.*]] = fir.box_addr %[[VAL_30:.*]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>) -> !fir.ptr<!fir.array<?xi32>>
-! CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.ptr<!fir.array<?xi32>>) -> i64
-! CHECK: %[[VAL_34:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
-! CHECK: %[[VAL_35:.*]] = fir.coordinate_of %[[VAL_31]], %[[VAL_34]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
+! CHECK-DAG: %[[VAL_32:.*]] = fir.box_addr %[[VAL_30:.*]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>) -> !fir.ptr<!fir.array<?xi32>>
+! CHECK-DAG: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.ptr<!fir.array<?xi32>>) -> i64
+! CHECK-DAG: %[[VAL_34:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
+! CHECK-DAG: %[[VAL_35:.*]] = fir.coordinate_of %[[VAL_31]], %[[VAL_34]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
! CHECK: fir.store %[[VAL_33]] to %[[VAL_35]] : !fir.ref<i64>
! CHECK: }
More information about the flang-commits
mailing list