This is an archive of the discontinued LLVM Phabricator instance.

[flang] Allow logical expressions as arguments with changed logical kind
ClosedPublic

Authored by DavidTruby on Aug 10 2023, 4:42 AM.

Details

Summary

This patch enables logical expressions to be used as arguments when the
default logical kind is changed (e.g. using -fdefault-integer-8) by
converting the type of the logical expression argument to the type of
the dummy argument in the function.

Diff Detail

Event Timeline

DavidTruby created this revision.Aug 10 2023, 4:42 AM
Herald added projects: Restricted Project, Restricted Project. · View Herald Transcript
DavidTruby requested review of this revision.Aug 10 2023, 4:42 AM

I'm not sure this is actually correct, and it doesn't deal with implicit subroutine/function calls yet, but it would be good to know if I am going in the right direction

Looks good so far.

Do the same conversions for implicit functions as explicit ones.

I have limited doing the conversion to when the argument is a result of a
relational operation or is a constant, as I think in other cases it is
incorrect.

Remove unnecessary includes added by editor

Do the same conversions for implicit functions as explicit ones.

I have limited doing the conversion to when the argument is a result of a
relational operation or is a constant, as I think in other cases it is
incorrect.

So you'll convert the result of X .EQ. Y but not (X .EQ. Y) .AND. (A .EQ. B)?

DavidTruby added a comment.EditedAug 10 2023, 10:40 AM

Do the same conversions for implicit functions as explicit ones.

I have limited doing the conversion to when the argument is a result of a
relational operation or is a constant, as I think in other cases it is
incorrect.

So you'll convert the result of X .EQ. Y but not (X .EQ. Y) .AND. (A .EQ. B)?

Good point. The main issue is if I allow it for all cases then e.g. the

call baz(any(l))

in the tests forces the any to have KIND=8 rather than the correct KIND=1.
Do you think there's a better way of doing this than just or-ing the different possible nodes as I have above? I could add logical operations as well but that might not be the only one I've missed...

Do the same conversions for implicit functions as explicit ones.

I have limited doing the conversion to when the argument is a result of a
relational operation or is a constant, as I think in other cases it is
incorrect.

So you'll convert the result of X .EQ. Y but not (X .EQ. Y) .AND. (A .EQ. B)?

Good point. The main issue is if I allow it for all types then e.g. the

call baz(any(l))

in the tests forces the any to have KIND=8 rather than the correct KIND=1.
Do you think there's a better way of doing this than just or-ing the different possible nodes as I have above? I could add logical operations as well but that might not be the only one I've missed...

I don't think that it matters what the actual argument expression is, so long as it is indeed an expression and not a variable.

DavidTruby added a comment.EditedAug 10 2023, 10:45 AM

I don't think that it matters what the actual argument expression is, so long as it is indeed an expression and not a variable.

I think it would give the implicitly declared subroutine for baz in the test case the wrong type, which could cause issues if that subroutine is defined in another translation unit? Then again I'm not 100% sure what the rules for implicitly defined subroutines are.

I don't think that it matters what the actual argument expression is, so long as it is indeed an expression and not a variable.

I think it would give the implicitly declared subroutine for baz in the test case the wrong type, which could cause issues if that subroutine is defined in another translation unit? Then again I'm not 100% sure what the rules for implicitly defined subroutines are.

That's right; never mind.

DavidTruby added a comment.EditedAug 10 2023, 1:24 PM

I think for explicitly declared functions we could allow that case to pass anyway, it would make sense at least to me (although it doesn't work on gfortran). For implicit functions we will need to be careful not to include it to not change the implicit declaration though. What I'm not sure about is from which direction would be better to restrict it (i.e., ! (FunctionCall || ...) or (Relational || Constant || ...) as is already there). Or if there might be a better way entirely.
The problem I hit when trying to do it from the other side is I had to include every kind, and still wasn't sure I'd excluded everything relevant.

I think for explicitly declared functions we could allow that case to pass anyway, it would make sense at least to me (although it doesn't work on gfortran). For implicit functions we will need to be careful not to include it to not change the implicit declaration though. What I'm not sure about is from which direction would be better to restrict it (i.e., ! (FunctionCall || ...) or (Relational || Constant || ...) as is already there). Or if there might be a better way entirely.
The problem I hit when trying to do it from the other side is I had to include every kind, and still wasn't sure I'd excluded everything relevant.

Yes, actual argument expressions (not variables) to specific procedures with explicit interfaces are generally safe to convert to the type of the dummy argument.

I am now somewhat more concerned with causing bad interactions with generic interface resolution.

I'll think about this some more and get back to you. We might just have to go with your original idea of removing LogicalResult after all.

DavidTruby added a comment.EditedAug 10 2023, 2:14 PM

Yes, actual argument expressions (not variables) to specific procedures with explicit interfaces are generally safe to convert to the type of the dummy argument.

In the short term the explicit interface case is actually in interaction that's causing an issue for us. Would you be ok with me going back to (something like) the patch I had yesterday where we just handle the explicit case while we consider the implicit case further?

Yes, actual argument expressions (not variables) to specific procedures with explicit interfaces are generally safe to convert to the type of the dummy argument.

In the short term the explicit interface case is actually in interaction that's causing an issue for us. Would you be ok with me going back to (something like) the patch I had yesterday where we just handle the explicit case while we consider the implicit case further?

Sure.

Reverted to only performing for explicit procedures

klausler accepted this revision.Aug 11 2023, 8:20 AM
This revision is now accepted and ready to land.Aug 11 2023, 8:20 AM