This is an archive of the discontinued LLVM Phabricator instance.

[flang] codegen for conversion between fp and logical
AbandonedPublic

Authored by tblah on Jun 13 2023, 9:44 AM.

Details

Summary

The IR verifier for fir.convert allows conversions between floating
point values and logical values, so I'm adding support here.

These converts can be generated using ENTRY statements with different
return types to the enclosing function and hlfir lowering.

Diff Detail

Event Timeline

tblah created this revision.Jun 13 2023, 9:44 AM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptJun 13 2023, 9:44 AM
tblah requested review of this revision.Jun 13 2023, 9:44 AM

Could you provide an example with ENTRY for this use case, I am a bit surprised the conversion is not done at the storage level.

tblah added a comment.Jun 14 2023, 2:34 AM

Could you provide an example with ENTRY for this use case, I am a bit surprised the conversion is not done at the storage level.

Based on https://github.com/llvm/llvm-test-suite/blob/main/Fortran/gfortran/torture/execute/entry_4.f90

function f4 (a) result (r)
  logical r
  integer a
  double precision t
  entry g4 (a) result (t)
  r = a .lt. a
end function

https://reviews.llvm.org/D152725 is needed to get to this error, but I don't think this is the convert added by that patch. It is possible that this bug will go away once I move the convert to before the hlfir.declare as you suggested. I haven't got that far yet. I already had this code written so I thought I may as well share it. Either way, I think we should either support this case in codegen or catch this in the verifier.

https://reviews.llvm.org/D152725 is needed to get to this error, but I don't think this is the convert added by that patch. It is possible that this bug will go away once I move the convert to before the hlfir.declare as you suggested. I haven't got that far yet. I already had this code written so I thought I may as well share it. Either way, I think we should either support this case in codegen or catch this in the verifier.

Thanks a lot for the explanation! I also think this fir.convert is a bug in the entry case. So I would favor a verifier error until there is a valid use case to ensure we catch such bugs.

It seems invalid to me to do a cast at the value level between the result types. The test is only testing returning .false. (a.lt.a) in a double precision storage. The test is not very thorough since .false. is implemented as zero, so the cast at the value level has the same effect as casting the storages. If the test was also testing the true case, I think the convert at the value level would likely give bad results:

module m
contains
function f4 (a) result (r)
  logical a, r
  real t
  entry g4 (a) result (t)
  r = a
end function
end module

  use m
  print*,  f4(.false.), g4(.false.)
  print*,  f4(.true.), g4(.true.)
end

With the logical representation that flang has, this should print (like gfortran):

F   0.00000000    
T   1.40129846E-45

But with a value level cast, this would likely print (I did not check):

F   0.00000000    
T   1.

Note that the original test is also a bit undefined depending on how g4() result is used because only part of the result storage is properly set by the function (double precision is bigger than default logical, so the upper bit of g4 result are undefined, they will likely be zeros, but not always....). Hence I used default real in my test variant.

tblah abandoned this revision.Jun 14 2023, 9:38 AM

https://reviews.llvm.org/D152725 is needed to get to this error, but I don't think this is the convert added by that patch. It is possible that this bug will go away once I move the convert to before the hlfir.declare as you suggested. I haven't got that far yet. I already had this code written so I thought I may as well share it. Either way, I think we should either support this case in codegen or catch this in the verifier.

Thanks a lot for the explanation! I also think this fir.convert is a bug in the entry case. So I would favor a verifier error until there is a valid use case to ensure we catch such bugs.

It seems invalid to me to do a cast at the value level between the result types. The test is only testing returning .false. (a.lt.a) in a double precision storage. The test is not very thorough since .false. is implemented as zero, so the cast at the value level has the same effect as casting the storages. If the test was also testing the true case, I think the convert at the value level would likely give bad results:

module m
contains
function f4 (a) result (r)
  logical a, r
  real t
  entry g4 (a) result (t)
  r = a
end function
end module

  use m
  print*,  f4(.false.), g4(.false.)
  print*,  f4(.true.), g4(.true.)
end

With the logical representation that flang has, this should print (like gfortran):

F   0.00000000    
T   1.40129846E-45

But with a value level cast, this would likely print (I did not check):

F   0.00000000    
T   1.

Note that the original test is also a bit undefined depending on how g4() result is used because only part of the result storage is properly set by the function (double precision is bigger than default logical, so the upper bit of g4 result are undefined, they will likely be zeros, but not always....). Hence I used default real in my test variant.

Ahh good point. I will abandon this patch and fix the verifier. See https://reviews.llvm.org/D152935