This is an archive of the discontinued LLVM Phabricator instance.

[flang] Fix calls to LBOUND() intrinsic for arrays with lower bounds not 1
ClosedPublic

Authored by PeteSteinfeld on Feb 2 2021, 2:16 PM.

Details

Summary

Constant folding for calls to LBOUND() was not working when the lower bound of
a constant array was not 1.

I fixed this and re-enabled the test in Evaluate/folding16.f90 that previously
was silently failing. I slightly changed the test to parenthesize the first
argument to exercise all of the new code.

Diff Detail

Event Timeline

PeteSteinfeld created this revision.Feb 2 2021, 2:16 PM
PeteSteinfeld requested review of this revision.Feb 2 2021, 2:16 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 2 2021, 2:16 PM
PeteSteinfeld added a project: Restricted Project.Feb 2 2021, 2:16 PM
tskeith added inline comments.Feb 2 2021, 6:57 PM
flang/lib/Evaluate/fold-integer.cpp
91

I noticed we already have UnwrapConstantValue, so I think you could write this as:

if (auto *constant{UnwrapConstantValue(*array)}) {
  return Expr<T>(constant->lbounds()[*dim]);
}
PeteSteinfeld added inline comments.Feb 2 2021, 9:31 PM
flang/lib/Evaluate/fold-integer.cpp
91

I have to confess that I find the interaction between the C++ types used in expression processing and template expansion confusing. But here's why I don't think I can use "UnwrapConstantValue".

Note that "UnwrapConstantValue" is a template function, so to call it, you need to supply a template parameter, something like:

if (auto *constant{UnwrapConstantValue<T>(*array)}) {
  return Expr<T>(constant->lbounds()[*dim]);
}

At this point in the code, the type of "T" is "Type<TypeCategory::Integer, KIND>". But the type needed to instantiate "UnwrapConstantValue" is the type of the first argument to LBOUND() which could be an array of any type. So if the type of the array is INTEGER, your suggestion might work. But it won't work if the argument is an array of type REAL.

The variable that contains the value of this first argument is "array". The type of "array" is "evaluate::Expr<SomeType>". So the type needed to correctly instantiate "UnwrapConstantValue" is wrapped up in the "evaluate::Expr<SomeType>", and I couldn't figure out how to extract it in a way to use it for the instantiation. So I wrote the class "GetConstantArrayLboundHelper" which extracts the lower bound without knowing the type of the array.

It's quite possible that there's a C++ technique that would let me avoid writing the class "GetConstantArrayLboundHelper". But I don't know what it is.

tskeith accepted this revision.Feb 3 2021, 8:55 AM
tskeith added inline comments.
flang/lib/Evaluate/fold-integer.cpp
91

OK, thanks for the explanation.

This revision is now accepted and ready to land.Feb 3 2021, 8:55 AM