Skip to content

Commit

Permalink
[flang] add fir.proc_attrs attributes to func.func (#110002)
Browse files Browse the repository at this point in the history
BIND(C) ABI need care in the TargetRewrite pass. currently, we are not
able to accurately identify fun.func that are BIND(C) in FIR (the
fir.bindc_name is used in other contexts, like for program names).

This patch adds the fir.proc_attrs to func.func just like it was done
for calls recently. This replace the previous named attribute for
PURE/ELEMENTAL/RECURSIVE (note that RECURSIVE is changed to
NON_RECURSIVE, which brings more data since RECURSIVE is the default for
procedures that do not have explicit RECURSIVE/NON_RECUSRIVE
attributes).
  • Loading branch information
jeanPerier authored Sep 26, 2024
1 parent 69ef3b1 commit d925006
Show file tree
Hide file tree
Showing 17 changed files with 84 additions and 64 deletions.
1 change: 1 addition & 0 deletions flang/include/flang/Lower/CallInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ class CallInterface {
CallInterface(Fortran::lower::AbstractConverter &c) : converter{c} {}
/// CRTP handle.
T &side() { return *static_cast<T *>(this); }
const T &side() const { return *static_cast<const T *>(this); }
/// Entry point to be called by child ctor to analyze the signature and
/// create/find the mlir::func::FuncOp. Child needs to be initialized first.
void declare();
Expand Down
4 changes: 4 additions & 0 deletions flang/include/flang/Optimizer/Dialect/FIROpsSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ static constexpr llvm::StringRef getFuncRecursiveAttrName() {
return "fir.func_recursive";
}

static constexpr llvm::StringRef getFortranProcedureFlagsAttrName() {
return "fir.proc_attrs";
}

// Attribute for an alloca that is a trivial adaptor for converting a value to
// pass-by-ref semantics for a VALUE parameter. The optimizer may be able to
// eliminate these.
Expand Down
44 changes: 27 additions & 17 deletions flang/lib/Lower/CallInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,7 @@ mlir::Value Fortran::lower::CalleeInterface::getHostAssociatedTuple() const {

static void addSymbolAttribute(mlir::func::FuncOp func,
const Fortran::semantics::Symbol &sym,
fir::FortranProcedureFlagsEnumAttr procAttrs,
mlir::MLIRContext &mlirContext) {
const Fortran::semantics::Symbol &ultimate = sym.GetUltimate();
// The link between an internal procedure and its host procedure is lost
Expand Down Expand Up @@ -611,16 +612,8 @@ static void addSymbolAttribute(mlir::func::FuncOp func,
}
}

// Set procedure attributes to the func op.
if (IsPureProcedure(sym))
func->setAttr(fir::getFuncPureAttrName(),
mlir::UnitAttr::get(&mlirContext));
if (IsElementalProcedure(sym))
func->setAttr(fir::getFuncElementalAttrName(),
mlir::UnitAttr::get(&mlirContext));
if (sym.attrs().test(Fortran::semantics::Attr::RECURSIVE))
func->setAttr(fir::getFuncRecursiveAttrName(),
mlir::UnitAttr::get(&mlirContext));
if (procAttrs)
func->setAttr(fir::getFortranProcedureFlagsAttrName(), procAttrs);

// Only add this on bind(C) functions for which the symbol is not reflected in
// the current context.
Expand Down Expand Up @@ -703,6 +696,7 @@ void Fortran::lower::CallInterface<T>::declare() {
func = fir::FirOpBuilder::getNamedFunction(module, symbolTable, name);
if (!func) {
mlir::Location loc = side().getCalleeLocation();
mlir::MLIRContext &mlirContext = converter.getMLIRContext();
mlir::FunctionType ty = genFunctionType();
func =
fir::FirOpBuilder::createFunction(loc, module, name, ty, symbolTable);
Expand All @@ -712,7 +706,8 @@ void Fortran::lower::CallInterface<T>::declare() {
mlir::StringAttr::get(&converter.getMLIRContext(),
sym->name().ToString()));
} else {
addSymbolAttribute(func, *sym, converter.getMLIRContext());
addSymbolAttribute(func, *sym, getProcedureAttrs(&mlirContext),
mlirContext);
}
}
for (const auto &placeHolder : llvm::enumerate(inputs))
Expand Down Expand Up @@ -1550,8 +1545,8 @@ template <typename T>
fir::FortranProcedureFlagsEnumAttr
Fortran::lower::CallInterface<T>::getProcedureAttrs(
mlir::MLIRContext *mlirContext) const {
fir::FortranProcedureFlagsEnum flags = fir::FortranProcedureFlagsEnum::none;
if (characteristic) {
fir::FortranProcedureFlagsEnum flags = fir::FortranProcedureFlagsEnum::none;
if (characteristic->IsBindC())
flags = flags | fir::FortranProcedureFlagsEnum::bind_c;
if (characteristic->IsPure())
Expand All @@ -1560,12 +1555,27 @@ Fortran::lower::CallInterface<T>::getProcedureAttrs(
flags = flags | fir::FortranProcedureFlagsEnum::elemental;
// TODO:
// - SIMPLE: F2023, not yet handled by semantics.
// - NON_RECURSIVE: not part of the characteristics. Maybe this should
// simply not be part of FortranProcedureFlagsEnum since cannot accurately
// be known on the caller side.
if (flags != fir::FortranProcedureFlagsEnum::none)
return fir::FortranProcedureFlagsEnumAttr::get(mlirContext, flags);
}

if constexpr (std::is_same_v<Fortran::lower::CalleeInterface, T>) {
// Only gather and set NON_RECURSIVE for procedure definition. It is
// meaningless on calls since this is not part of Fortran characteristics
// (Fortran 2023 15.3.1) so there is no way to always know if the procedure
// called is recursive or not.
if (const Fortran::semantics::Symbol *sym = side().getProcedureSymbol()) {
// Note: By default procedures are RECURSIVE unless
// -fno-automatic/-save/-Msave is set. NON_RECURSIVE is is made explicit
// in that case in FIR.
if (sym->attrs().test(Fortran::semantics::Attr::NON_RECURSIVE) ||
(sym->owner().context().languageFeatures().IsEnabled(
Fortran::common::LanguageFeature::DefaultSave) &&
!sym->attrs().test(Fortran::semantics::Attr::RECURSIVE))) {
flags = flags | fir::FortranProcedureFlagsEnum::non_recursive;
}
}
}
if (flags != fir::FortranProcedureFlagsEnum::none)
return fir::FortranProcedureFlagsEnumAttr::get(mlirContext, flags);
return nullptr;
}

Expand Down
16 changes: 8 additions & 8 deletions flang/test/Lower/CUDA/cuda-device-proc.cuf
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ end
! CHECK: %{{.*}} = fir.call @__syncthreads_count(%{{.*}}) proc_attrs<bind_c> fastmath<contract> : (!fir.ref<i32>) -> i32
! CHECK: %{{.*}} = fir.call @__syncthreads_or(%{{.*}}) proc_attrs<bind_c> fastmath<contract> : (!fir.ref<i32>) -> i32

! CHECK: func.func private @__syncthreads() attributes {cuf.proc_attr = #cuf.cuda_proc<device>, fir.bindc_name = "__syncthreads"}
! CHECK: func.func private @__syncwarp(!fir.ref<i32> {cuf.data_attr = #cuf.cuda<device>}) attributes {cuf.proc_attr = #cuf.cuda_proc<device>, fir.bindc_name = "__syncwarp"}
! CHECK: func.func private @__threadfence() attributes {cuf.proc_attr = #cuf.cuda_proc<device>, fir.bindc_name = "__threadfence"}
! CHECK: func.func private @__threadfence_block() attributes {cuf.proc_attr = #cuf.cuda_proc<device>, fir.bindc_name = "__threadfence_block"}
! CHECK: func.func private @__threadfence_system() attributes {cuf.proc_attr = #cuf.cuda_proc<device>, fir.bindc_name = "__threadfence_system"}
! CHECK: func.func private @__syncthreads_and(!fir.ref<i32> {cuf.data_attr = #cuf.cuda<device>}) -> i32 attributes {cuf.proc_attr = #cuf.cuda_proc<device>, fir.bindc_name = "__syncthreads_and"}
! CHECK: func.func private @__syncthreads_count(!fir.ref<i32> {cuf.data_attr = #cuf.cuda<device>}) -> i32 attributes {cuf.proc_attr = #cuf.cuda_proc<device>, fir.bindc_name = "__syncthreads_count"}
! CHECK: func.func private @__syncthreads_or(!fir.ref<i32> {cuf.data_attr = #cuf.cuda<device>}) -> i32 attributes {cuf.proc_attr = #cuf.cuda_proc<device>, fir.bindc_name = "__syncthreads_or"}
! CHECK: func.func private @__syncthreads() attributes {cuf.proc_attr = #cuf.cuda_proc<device>, fir.bindc_name = "__syncthreads", fir.proc_attrs = #fir.proc_attrs<bind_c>}
! CHECK: func.func private @__syncwarp(!fir.ref<i32> {cuf.data_attr = #cuf.cuda<device>}) attributes {cuf.proc_attr = #cuf.cuda_proc<device>, fir.bindc_name = "__syncwarp", fir.proc_attrs = #fir.proc_attrs<bind_c>}
! CHECK: func.func private @__threadfence() attributes {cuf.proc_attr = #cuf.cuda_proc<device>, fir.bindc_name = "__threadfence", fir.proc_attrs = #fir.proc_attrs<bind_c>}
! CHECK: func.func private @__threadfence_block() attributes {cuf.proc_attr = #cuf.cuda_proc<device>, fir.bindc_name = "__threadfence_block", fir.proc_attrs = #fir.proc_attrs<bind_c>}
! CHECK: func.func private @__threadfence_system() attributes {cuf.proc_attr = #cuf.cuda_proc<device>, fir.bindc_name = "__threadfence_system", fir.proc_attrs = #fir.proc_attrs<bind_c>}
! CHECK: func.func private @__syncthreads_and(!fir.ref<i32> {cuf.data_attr = #cuf.cuda<device>}) -> i32 attributes {cuf.proc_attr = #cuf.cuda_proc<device>, fir.bindc_name = "__syncthreads_and", fir.proc_attrs = #fir.proc_attrs<bind_c>}
! CHECK: func.func private @__syncthreads_count(!fir.ref<i32> {cuf.data_attr = #cuf.cuda<device>}) -> i32 attributes {cuf.proc_attr = #cuf.cuda_proc<device>, fir.bindc_name = "__syncthreads_count", fir.proc_attrs = #fir.proc_attrs<bind_c>}
! CHECK: func.func private @__syncthreads_or(!fir.ref<i32> {cuf.data_attr = #cuf.cuda<device>}) -> i32 attributes {cuf.proc_attr = #cuf.cuda_proc<device>, fir.bindc_name = "__syncthreads_or", fir.proc_attrs = #fir.proc_attrs<bind_c>}
4 changes: 2 additions & 2 deletions flang/test/Lower/HLFIR/bindc-value-derived.f90
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ subroutine test(x) bind(c)
call use_it(x%i)
end subroutine
! CHECK-LABEL: func.func @test(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.type<_QMbindc_byvalTt{i:i32}> {fir.bindc_name = "x"}) attributes {fir.bindc_name = "test"} {
! CHECK-SAME: %[[VAL_0:.*]]: !fir.type<_QMbindc_byvalTt{i:i32}>
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QMbindc_byvalTt{i:i32}>
! CHECK: fir.store %[[VAL_0]] to %[[VAL_1]] : !fir.ref<!fir.type<_QMbindc_byvalTt{i:i32}>>
! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs<value>, uniq_name = "_QMbindc_byvalFtestEx"} : (!fir.ref<!fir.type<_QMbindc_byvalTt{i:i32}>>, !fir.dscope) -> (!fir.ref<!fir.type<_QMbindc_byvalTt{i:i32}>>, !fir.ref<!fir.type<_QMbindc_byvalTt{i:i32}>>)
Expand All @@ -28,7 +28,7 @@ subroutine call_it(x)
call test(x)
end subroutine
! CHECK-LABEL: func.func @_QMbindc_byvalPcall_it(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.type<_QMbindc_byvalTt{i:i32}>> {fir.bindc_name = "x"}) {
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.type<_QMbindc_byvalTt{i:i32}>>
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %{{[0-9]+}} {uniq_name = "_QMbindc_byvalFcall_itEx"} : (!fir.ref<!fir.type<_QMbindc_byvalTt{i:i32}>>, !fir.dscope) -> (!fir.ref<!fir.type<_QMbindc_byvalTt{i:i32}>>, !fir.ref<!fir.type<_QMbindc_byvalTt{i:i32}>>)
! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_1]]#1 : !fir.ref<!fir.type<_QMbindc_byvalTt{i:i32}>>
! CHECK: fir.call @test(%[[VAL_2]]) proc_attrs<bind_c> fastmath<contract> : (!fir.type<_QMbindc_byvalTt{i:i32}>) -> ()
Expand Down
2 changes: 1 addition & 1 deletion flang/test/Lower/HLFIR/block_bindc_pocs.f90
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ end module m
!CHECK-DAG: %[[S0:.*]] = llvm.intr.stacksave : !llvm.ptr
!CHECK-DAG: fir.call @test_proc() proc_attrs<bind_c> fastmath<contract> : () -> ()
!CHECK-DAG: llvm.intr.stackrestore %[[S0]] : !llvm.ptr
!CHECK-DAG: func.func private @test_proc() attributes {fir.bindc_name = "test_proc"}
!CHECK-DAG: func.func private @test_proc() attributes {fir.bindc_name = "test_proc", fir.proc_attrs = #fir.proc_attrs<bind_c>}
subroutine test
BLOCK
use m
Expand Down
4 changes: 2 additions & 2 deletions flang/test/Lower/Intrinsics/signal.f90
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
module m
contains
! CHECK-LABEL: func.func @handler(
! CHECK-SAME: %[[VAL_0:.*]]: i32 {fir.bindc_name = "signum"}) attributes {fir.bindc_name = "handler"} {
! CHECK-SAME: %[[VAL_0:.*]]: i32
subroutine handler(signum) bind(C)
use iso_c_binding, only: c_int
integer(c_int), value :: signum
end subroutine

! CHECK-LABEL: func.func @_QMmPsetup_signals(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<i32> {fir.bindc_name = "optional_status", fir.optional}) {
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<i32>
subroutine setup_signals(optional_status)
! not portable accross systems
integer, parameter :: SIGFPE = 8
Expand Down
4 changes: 2 additions & 2 deletions flang/test/Lower/OpenMP/declare-target-func-and-subr.f90
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ SUBROUTINE SUBR_DEFAULT_EXTENDEDLIST()
!! -----

! DEVICE-LABEL: func.func @_QPrecursive_declare_target
! DEVICE-SAME: {{.*}}attributes {fir.func_recursive, omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}
! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}
RECURSIVE FUNCTION RECURSIVE_DECLARE_TARGET(INCREMENT) RESULT(K)
!$omp declare target to(RECURSIVE_DECLARE_TARGET) device_type(nohost)
INTEGER :: INCREMENT, K
Expand All @@ -166,7 +166,7 @@ RECURSIVE FUNCTION RECURSIVE_DECLARE_TARGET(INCREMENT) RESULT(K)
END FUNCTION RECURSIVE_DECLARE_TARGET

! DEVICE-LABEL: func.func @_QPrecursive_declare_target_enter
! DEVICE-SAME: {{.*}}attributes {fir.func_recursive, omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>{{.*}}
! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>{{.*}}
RECURSIVE FUNCTION RECURSIVE_DECLARE_TARGET_ENTER(INCREMENT) RESULT(K)
!$omp declare target enter(RECURSIVE_DECLARE_TARGET_ENTER) device_type(nohost)
INTEGER :: INCREMENT, K
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ end function target_function_test_host
!! -----

! DEVICE-LABEL: func.func @_QPimplicitly_captured_with_dev_type_recursive
! DEVICE-SAME: {{.*}}attributes {fir.func_recursive, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>{{.*}}}
! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>{{.*}}}
recursive function implicitly_captured_with_dev_type_recursive(increment) result(k)
!$omp declare target enter(implicitly_captured_with_dev_type_recursive) device_type(host)
integer :: increment, k
Expand Down Expand Up @@ -174,7 +174,7 @@ recursive subroutine implicitly_captured_recursive(increment)
end program

! DEVICE-LABEL: func.func @_QPimplicitly_captured_recursive
! DEVICE-SAME: {{.*}}attributes {fir.func_recursive, omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>{{.*}}}
! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>{{.*}}}
recursive subroutine implicitly_captured_recursive(increment)
integer :: increment
if (increment == 10) then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ end function target_function_test_host
!! -----

! DEVICE-LABEL: func.func @_QPimplicitly_captured_with_dev_type_recursive
! DEVICE-SAME: {{.*}}attributes {fir.func_recursive, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}}
! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}}
recursive function implicitly_captured_with_dev_type_recursive(increment) result(k)
!$omp declare target to(implicitly_captured_with_dev_type_recursive) device_type(host)
integer :: increment, k
Expand Down Expand Up @@ -200,7 +200,7 @@ recursive subroutine implicitly_captured_recursive(increment)
end program

! DEVICE-LABEL: func.func @_QPimplicitly_captured_recursive
! DEVICE-SAME: {{.*}}attributes {fir.func_recursive, omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}}
! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}}
recursive subroutine implicitly_captured_recursive(increment)
integer :: increment
if (increment == 10) then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ end function target_function_test_device
!! -----

! DEVICE-LABEL: func.func @_QPimplicitly_captured_recursive
! DEVICE-SAME: {{.*}}attributes {fir.func_recursive, omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}}
! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}}
recursive function implicitly_captured_recursive(increment) result(k)
integer :: increment, k
if (increment == 10) then
Expand Down
8 changes: 4 additions & 4 deletions flang/test/Lower/bindc_procs.f90
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
! RUN: bbc -emit-fir %s -o - | FileCheck %s

! CHECK-DAG: func.func private @proc1() attributes {fir.bindc_name = "proc1"}
! CHECK-DAG: func.func private @proc1() attributes {fir.bindc_name = "proc1", fir.proc_attrs = #fir.proc_attrs<bind_c>}
module decl1
interface
subroutine proc_iface() bind(C)
Expand All @@ -13,7 +13,7 @@ subroutine test1(x)
call PrOc1
end subroutine test1

! CHECK-DAG: func.func private @proc2() attributes {fir.bindc_name = "proc2"}
! CHECK-DAG: func.func private @proc2() attributes {fir.bindc_name = "proc2", fir.proc_attrs = #fir.proc_attrs<bind_c>}
module decl2
interface
subroutine proc_iface() bind(C)
Expand All @@ -26,7 +26,7 @@ subroutine test2(x)
call PrOc2
end subroutine test2

! CHECK-DAG: func.func private @func3() -> f32 attributes {fir.bindc_name = "func3"}
! CHECK-DAG: func.func private @func3() -> f32 attributes {fir.bindc_name = "func3", fir.proc_attrs = #fir.proc_attrs<bind_c>}
module decl3
interface
real function func_iface() bind(C)
Expand All @@ -40,7 +40,7 @@ subroutine test3(x)
x = FuNc3()
end subroutine test3

! CHECK-DAG: func.func private @func4() -> f32 attributes {fir.bindc_name = "func4"}
! CHECK-DAG: func.func private @func4() -> f32 attributes {fir.bindc_name = "func4", fir.proc_attrs = #fir.proc_attrs<bind_c>}
module decl4
interface
real function func_iface() bind(C)
Expand Down
4 changes: 2 additions & 2 deletions flang/test/Lower/c-interoperability-c-pointer.f90
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ subroutine c_func(c_t1, c_t2) bind(c, name="c_func")
end

! CHECK-LABEL: func.func @test_callee_c_ptr(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<i64> {fir.bindc_name = "ptr1"}) attributes {fir.bindc_name = "test_callee_c_ptr"} {
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<i64>
! CHECK: %[[VAL_5:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> {bindc_name = "local", uniq_name = "_QFtest_callee_c_ptrElocal"}
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
! CHECK: %[[VAL_2:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
Expand All @@ -56,7 +56,7 @@ subroutine test_callee_c_ptr(ptr1) bind(c)
end subroutine

! CHECK-LABEL: func.func @test_callee_c_funptr(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<i64> {fir.bindc_name = "ptr1"}) attributes {fir.bindc_name = "test_callee_c_funptr"} {
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<i64>
! CHECK: %[[VAL_5:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}> {bindc_name = "local", uniq_name = "_QFtest_callee_c_funptrElocal"}
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>
! CHECK: %[[VAL_2:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>
Expand Down
2 changes: 1 addition & 1 deletion flang/test/Lower/call.f90
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ function f_int_to_char(i) bind(c, name="f_int_to_char")
end function

! CHECK-LABEL: func.func @f_int_to_char(
! CHECK-SAME: %[[ARG0:.*]]: i32 {fir.bindc_name = "i"}) -> !fir.char<1> attributes {fir.bindc_name = "f_int_to_char"} {
! CHECK-SAME: %[[ARG0:.*]]: i32 {fir.bindc_name = "i"}) -> !fir.char<1> attributes {fir.bindc_name = "f_int_to_char", fir.proc_attrs = #fir.proc_attrs<bind_c>} {
! CHECK: %[[CHARBOX:.*]] = fir.alloca !fir.char<1> {adapt.valuebyref}
! CHECK: %[[RESULT:.*]] = fir.alloca !fir.char<1> {bindc_name = "f_int_to_char", uniq_name = "_QFf_int_to_charEf_int_to_char"}
! CHECK: %[[INT_I:.*]] = fir.alloca i32
Expand Down
Loading

0 comments on commit d925006

Please sign in to comment.