This is an archive of the discontinued LLVM Phabricator instance.

[flang] Add support for lowering intrinsic module procedure C_ASSOCIATED
ClosedPublic

Authored by peixin on Oct 21 2022, 12:09 AM.

Details

Summary

As Fortran 2018 18.2.3.2, the arguments of C_ASSOCIATED have the same
type, a scalar of type C_PTR or C_FUNPTR, and the result has the default
logical scalar type. The interface is defined with two module procedures
c_associated_c_ptr/c_associated_c_funptr in flang/module/iso_c_binding.
The result is false if the first argument is a C null pointer. If the
second argument is present, the result is true only if the two arguments
are equal. Support the lowering by comparing the C pointer address
values of two arguments if the second argument is dynamically present
and comparing the C pointer address value of the first argument with the
value 0.

Diff Detail

Event Timeline

peixin created this revision.Oct 21 2022, 12:09 AM
Herald added a project: Restricted Project. · View Herald Transcript
peixin requested review of this revision.Oct 21 2022, 12:09 AM

Is this working for the dynamic optional case ? I see the "asValue, handleDynamicOptional" in the table, but I am not sure it is intended for derived types (*), and since the second argument load is unconditional, I wonder if this really works for the test_3 below:

module tests
contains
subroutine test_3(cptr1, cptr2)
  use iso_c_binding
  type(c_ptr) :: cptr1
  type(c_ptr), optional :: cptr2
  print *, c_associated(cptr1, cptr2)
end

subroutine test_3_driver()
  use iso_c_binding
  type(c_ptr) :: cptr1
  integer, target :: i
  cptr1 = c_loc(i)
  call test_3(cptr1)
  call test_3(cptr1, cptr1)
end subroutine
end module

  use tests
  call test_3_driver()
end

I think you might want to use asAddr and check that the second argument address is not null to conditionally load it and compare it.

(*) I think the intent was for this to not even compile according to this assert: https://github.com/llvm/llvm-project/blob/https://github.com/llvm/llvm-project/commit/dfcc0a70cc5d2fb8d2687105e9b9745dbf6a5cda/flang/lib/Lower/ConvertExpr.cpp#L431

peixin updated this revision to Diff 470411.Oct 25 2022, 1:55 AM
peixin edited the summary of this revision. (Show Details)
peixin updated this revision to Diff 470419.Oct 25 2022, 2:07 AM

Rebase due to conflict.

Is this working for the dynamic optional case ? I see the "asValue, handleDynamicOptional" in the table, but I am not sure it is intended for derived types (*), and since the second argument load is unconditional, I wonder if this really works for the test_3 below:

module tests
contains
subroutine test_3(cptr1, cptr2)
  use iso_c_binding
  type(c_ptr) :: cptr1
  type(c_ptr), optional :: cptr2
  print *, c_associated(cptr1, cptr2)
end

subroutine test_3_driver()
  use iso_c_binding
  type(c_ptr) :: cptr1
  integer, target :: i
  cptr1 = c_loc(i)
  call test_3(cptr1)
  call test_3(cptr1, cptr1)
end subroutine
end module

  use tests
  call test_3_driver()
end

I think you might want to use asAddr and check that the second argument address is not null to conditionally load it and compare it.

(*) I think the intent was for this to not even compile according to this assert: https://github.com/llvm/llvm-project/blob/https://github.com/llvm/llvm-project/commit/dfcc0a70cc5d2fb8d2687105e9b9745dbf6a5cda/flang/lib/Lower/ConvertExpr.cpp#L431

You are right. I missed the possibility of dynamic optional argument. Fixed as suggested. Thanks a lot.

jeanPerier accepted this revision.Oct 25 2022, 9:37 AM

LGTM, thanks

This revision is now accepted and ready to land.Oct 25 2022, 9:37 AM