Add and use the CONCAT macro to force the expansion of __LINE__ in
PushSemantics body.
Reviewed By: clementval
Differential Revision: https://reviews.llvm.org/D153460
Elemental procedures may need their array arguments to be passed by
address. This is done by setting ArrayExprLowering::semant to a
value that corresponds to this semantics. Later, member functions
such as applyPathToArrayLoad() read this variable to generate FIR
instructions that match the needed behavior. The problem is that
the semant variable also affects how array paths are lowered. Thus,
if an index of the path is an array element, this will cause its
address to be used instead of its value, which usually results in a
segmentation fault at runtime.
Example: b(i:i) = elem_func(a(v(i):v(i)))
To fix this, ArrayExprLowering::nextPathSemant was added. When it's
set, the next array path is handled with the semantics specified by
it, while the elemental argument retains its original semantics.
Fixes https://github.com/llvm/llvm-project/issues/62981
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D153454
There are several observations regarding the copy-in/copy-out:
* Actual argument associated with INTENT(OUT) dummy argument that
requires finalization (7.5.6.3 p. 7) may be read by the finalization
function, so a copy-in is required.
* A temporary created for the copy-in/copy-out must be destroyed
without finalization after the call (or after the corresponding copy-out),
otherwise, memory leaks may occur.
* The copy-out assignment must not perform finalization for the LHS.
* The copy-out assignment from the temporary to the actual argument
may or may not need to initialize the LHS.
This change-set introduces new runtime methods: CopyOutAssign and
DestroyWithoutFinalization. They are called by the compiler generated
code to match the behavior described above.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D151135
Currently complex division is lowered to a fir.divc operation and the
fir.divc is later converted to a sequence of llvm operations to perform
complex division, however this causes issues for extreme values when
the calculations overflow.
This patch changes the lowering of complex division to use the Intrinsic
Call functionality to lower into library calls (for single, double,
extended and quad precisions) or an MLIR complex dialect division operation
(for half and bfloat precisions).
A new wrapper function `genLibSplitComplexArgsCall` is written to handle
the case of the arguments of the Complex Library calls being split to
its real and imaginary real components.
Note 1: If the Complex To Standard conversion of division operation
matures then we can use it for all precisions. Currently it has the
same issues as the conversion of fir.divc.
Note 2: A previous patch (D145808) did the same but during conversion of
the fir.divc operation. But using function calls at that stage leads to
ABI issues since the conversion to LLVM is not aware of the complex target
rewrite.
Note 3: If the patch is accepted, fir.divc can be removed from FIR. We
can use the complex.div operation where any transformation is required.
Reviewed By: vzakhari, PeteSteinfeld, DavidTruby, jeanPerier
Differential Revision: https://reviews.llvm.org/D149546
The implied-do index value has 'index' type, and it has to be
converted to the original ac-do-variable's data type.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D150150
Currently complex division is lowered to a fir.divc operation and the
fir.divc is later converted to a sequence of llvm operations to perform
complex division, however this causes issues for extreme values when
the calculations overflow.
This patch changes the lowering of complex division to use the Intrinsic
Call functionality to lower into library calls (for single, double,
extended and quad precisions) or an MLIR complex dialect division operation
(for half and bfloat precisions).
Note 1: If the Complex To Standard conversion of division operation
matures then we can use it for all precisions. Currently it has the
same issues as the conversion of fir.divc.
Note 2: A previous patch (D145808) did the same but during conversion of
the fir.divc operation. But using function calls at that stage leads to
ABI issues since the conversion to LLVM is not aware of the complex target
rewrite.
Note 3: If the patch is accepted, fir.divc can be removed from FIR.
Reviewed By: vzakhari, PeteSteinfeld, DavidTruby
Differential Revision: https://reviews.llvm.org/D149546
- Fix the BIND(C) assumed-shape case: TYPE(*) assumed shape are passed
via CFI_cdesc_t according to Fortran 2018 standard 18.3.6 point 2 (5).
- Align the none BIND(C) case with the BIND(C) case. There is little
point passing TYPE(*) assumed size via descriptor, use a simple
address. C710 ensures there is no way the knowledge of the actual
type will be required when manipulating the dummy.
Differential Revision: https://reviews.llvm.org/D148130
The current lowering fails to retrieve the shape of polymorphic array
arguments in elemental procedure reference.
Add a TODO because this is supported in the new HLFIR lowering, and
because the current lowering anyway attempts to re-evaluate the
argument to get its shape, which is not correct if the evaluation
has side effects.
Add a test to ensure this is supported with HLFIR.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D148087
Fix invalid op result access. This will trigger
assertion introduced in D147883.
Reviewed By: frgossen
Differential Revision: https://reviews.llvm.org/D147959
Keep the extended value when lowering optional assumed type
dummy argument. The extended value is needed to lower correctly the
rest of the code.
Reviewed By: PeteSteinfeld, jeanPerier
Differential Revision: https://reviews.llvm.org/D147575
Assumed type are represented differently in the ActualArgument
class. Correctly handle them in intrinsic arg lowering.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D147487
The current code is wrong: it is doing an alloca with the declared
type instead of the dynamic type, leading to undefined behavior
when the dynamic type and declared type differ and the temporary
is later used.
This also introduces some `fir.alloca none` for unlimited polymorphic that
are not allocating the right thing at all.
Add TODOs for now, the correct thing to do will probably be to use the
runtime (like AssignTemporary), but since this happens in code doing
"mold" temp allocation, I first need to check if there is a need for "mold"
temporary creation not followed by an assign, or if this can be combined
with the assign instead (for HLFIR, it is pretty easy combine this from as_expr
codegen, not sure for the current lowering).
Differential Revision: https://reviews.llvm.org/D147333
The current context less lowering of NULL is producing invalid code
(can lead to reading outside of allocated memory): it is casting
a simple pointer to a descriptor address.
Later, reads are made to this descriptor. It used to be "OK" when
fir.load of fir.box were no-ops, but this was incorrect, and the
fir.load codegen is known doing a copy, and read the whole descriptor
data, not only the base address.
The previous patch that allowed fir.box<None> allocation, this
code fix this by allocating an actual fir.box<None>.
Note: this is still an overkill way to lower foo(null()). HLFIR
lowering always contextualize NULL() lowering leading to much simpler
code:
```
%absent = fir.absent fir.box<T>
fir.call @foo(%absent)
```
Differential Revision: https://reviews.llvm.org/D147239
ASSOCIATED intrinsic TARGET handling is weird for OPTIONAL, because as
opposed to other intrinsic arguments, OPTIONAL allocatable and pointers
may be absent when passed to it, and a diassociated pointer TARGET is not
the same as when TARGET is not provided. Hence, it needs custom
handling in lowering.
The handling was done late (in genIntrinsicCall, without the semantic
context), and assumed it would be possible to retrieve the optionality
aspects, but this is brittle, and hard to share with HLFIR.
Move it in CustomIntrinsicCall that is intended to deal with these
corner case.
Also avoid using fir.box<None> as the related fir.if result, and used
the correct fir.box/fir.class type for the target: using a fir.box<None>
here is risky since fir.box<None> are now meant for scalar TYPE(*), and
the TARGET may be ranked.
Move the introduction of the fir.box<None> around the runtime (when
assumed rank are supported, these will become !fir.box<!fir.array<..xNone>>).
Differential Revision: https://reviews.llvm.org/D147224
The dyanmic type must be carried over in a PolymorphicValue when the address is
loaded from an unlimited polymorphic allocatable.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D146525
Just use conversion from assuemd type to assumed type
because a rebox needs more information that are not available
with assumed type.
Also use `isAssumedType` instead of `isBoxNone` since assumed
type can have sequence information.
Depends on D146207
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D146209
When passing an argument to an assumed type dummy argument, embox
it directly to a !fir.box<none> box.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D146207
Fortran allows type mismatch when passing actual arguments to
procedures and most cases were already being handled correctly by
Flang. However, conversion of data types to and from procedures and
conversion between procedures and char procedures were not always
handled properly. The missing cases were added and these
conversions are supported now.
Fixes#60550
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D145601
In some cases the argument is already handled by a fir.rebox operation. Just
adapat the type to match the parent component in that case.
Depends on D145928
Differential Revision: https://reviews.llvm.org/D145931
When the argument is a parent component the box needs to
be updated to reflect the correct type. Use `updateBoxForParentComponent`
to update the argument accordingly.
Depends on D145907
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D145928
When the argument is a parent component the box needs to
be updated to reflect the correct type. Use `updateBoxForParentComponent`
to update the argument accordingly.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D145907
When the base box is a block argument, the defining op is null.
Only try to recover embox/rebox if there is a defining op.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D145910
This patch simplify the parent component handling when it's the last ref.
The first field is not necessary when the target box type is set correctly.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D145795
Optional character function arguments were not being lowered
properly. As they are passed as a tuple, containing the (boxed)
function address and the character length, it is not possible for
fir.absent to handle it directly. Instead, a tuple needs to be
created and filled with an absent function address and a dummy
character length.
Fixes#60225
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D144743
In select type construct the associating entity in a TYPE IS
type guard statement is obtained with a fir.convert. Update the code
for the parent component to support fir.convert defining op
as well.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D145367
Intrinsic module procedures are a bit different from intrinsic
procedures: they are defined in intrinsic module files, but their
signature and representation in semantics is the same as user
procedures.
The code to lower them in lowering (when they are not implemented in
Fortran) is the same as for intrinsic procedures
(Optimizer/Builder/IntrinsicCall.cpp).
The dispatching in in HLFIR procedure reference lowering must be
slightly modified so that these evaluate::ProcRef that have a
semantics::Symbol instead of an evaluate::SpecificIntrinsic can
be dispatched as evaluate::SpecificIntrinsic:
- move isIntrinsicModuleProcedure to detect them
- in the helpers dealing with intrinsics, make evaluate::SpecificIntrinsic
a pointer argument that can be null for intrinsic module procedures.
- add getProcedureName() to call context to avoid relying on the
evaluate::SpecificIntrinsic when it is not know to be null.
Differential Revision: https://reviews.llvm.org/D145360
Current code are crashing on the assert `assert(seqTy && "must be an array");`.
Add a TODO instead until the support is in.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D144173
When an optional intrinsic scalar is passed to a function expecting an
unlimited polymorphic dummy argument, the presence test must be done
before the emboxing otherwise it will result in a program crash.
Depends on D143888
Reviewed By: jeanPerier, PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D143889
Force TRANSPOSE with polymorphic inputs through the runtime call
and carry the polymorphic type information from the matrix to
the result.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D143709
Code move without any change, the goal is to re-use this piece of
code for procedure designator lowering in HLFIR since there is no
significant changes in the way procedure designators will be
lowered.
Differential Revision: https://reviews.llvm.org/D143563
Creation of polymorphic array temporary cannot be done inlined.
Add a TODO so the current code exit in a clean way when lowering
reach it. A solution involving the runtime will be put in place.
Depends on D143490
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D143491
HLFIR requires mapping symbol to a single mlir::Value (produced
by a fir::FortranVariableOpInterface), while the current lowering
maps the value to a fir::ExtdendedValue.
So far, the HLFIR symbol query was a special one. Hence, all the code
directly using symMap.lookupSymbol and symMap.addSymbol did not work
with the lowering to HLFIR.
Refactor the code so that symbol lookup and add symbol go through
the converter in a centralize place that handles the HLFIR case
(translate fir::FortranVariableOpInterface to fir::ExtdendedValue
in lookups, and generate hlfir.declare when adding symbols).
In the refactoring, fir::FortranVariableOpInterface is added as
a symbolBox variant to avoid special casing all lookups (shallowLookup...).
Remove some unused SymbolBox member function instead of updating
them.
Differential Revision: https://reviews.llvm.org/D143395
This will allow IntrinsicCall to be used in passes to implement hlfir
transformational intrinsic operations.
Differential Revision: https://reviews.llvm.org/D143084
When referencing a single component from a polymorphic array in an expression,
the rebox operation should output a boxed array of that component type and
not a polymorphic boxed array as it was done.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D142462
Only updates the assert to check where the box is a BaseBoxType
instead of a BoxType since ClassType are also valid in that case.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D142442
Make sure the source passed to an intrinsic is still polymorphic when
it is an element of a polymorphic array. This was not handled properly
before.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D142380
When a `!fir.box<>` is passed as an actual argument to an optional
`!fir.class<>` dummy it needs a `fir.rebox` in order to propagate
the dynamic type information.
The `fir.rebox` needs to happen only on present argument.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D142340
NULL() passed as actual argument to a procedure with an optional
dummy argument is represented with `fir.box<none>` type. When the dummy
argument is polymoprhic or unlimited polymorphic, the SelectOp will complain
if the types of the two arguments are not identical. Add a conversion from
`fir.box<none>` to `fir.class<none>` in that case.
Other situations with optional will require a fir.rebox and will be done in
a follow up patch.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D142203
Until now, only the address of the type descriptor was hold in
a PolymorphicValue. In some cases, the element size and the
type code are also needed when creating new polymorphic
descriptors from an element of a polymorphic entity.
This patch updates PolymorphicValue to carry the source
descriptor from which the element is extracted. The source
descriptor is then used when emboxing the element to a new
polymorphic descriptor.
This simplify the code done in D141274 and will be used
when creating polymorphic temporary as well.
Reviewed By: jeanPerier, PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D141609
This supports the lowering of intrinsic IS_CONTIGUOUS for array argument.
The argument of assumed rank is not supported since it is not implemented
yet as the procedure argument. Add TODO for it.
Reviewed By: PeteSteinfeld, jeanPerier
Differential Revision: https://reviews.llvm.org/D141212
Deallocation of intent(out) allocatable was done in D133348. This patch adds
an if guard when the deallocation is done through a runtime call. The runtime
is crashing if the box is not allocated. Call the runtime only if the box is
allocated. This is the case for derived type, polymorphic and unlimited
polymorphic entities.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D141427
A previous patch (https://reviews.llvm.org/D136955) already refactored
intrinsic constant lowering to place in its own file and allow using it from
both the current lowering and the new lowering to HLFIR.
This patch does the same for derived types. The core function
"genStructComponentInInitializer" is moved from ConvertExpr.cpp and
renamed "genInlinedStructureCtorLitImpl" into ConvertConstant.cpp
without significant logic change.
Then, genScalarLit, genArrayLit (and genInlinedArrayLit/genOutlinedArrayLit)
are updated to support derived types.
The core aspect of derived type constant lowering that differs between
the current lowering and the HLFIR update is the way
addresses/initial target descriptors are built when part of a derived
type constant. This part happens in ConvertVariable.cpp (since the
address of a variable is taken in an initializer and is left TODO).
The mangling of derived type global literal constant is fixed: it did not embed
the derived type name and could cause "conflicts" between unrelated
derived types containing the same data. However, the hash remains
unstable between two compilation of the same file. This is not a
correctness issue and would require a lot of work to hash the derived
type constant data without hashing some irrelevant (but not out of bound)
data in the compile time data structure that holds derived type
constants (Constant<SomeDerived>). This may have to be revisited later.
Differential Revision: https://reviews.llvm.org/D140986
Recent commits (2098ad7f00 and
15a9a72ee6) replaced usage of "o.value()"
on optionals with "*o". Those optional values are expected to be
present -- but now, if it ever turns out that they're not,
compilation will proceed with garbage data rather than crashing
immediately (and more debuggably) with an uncaught exception.
Add asserts for presence to restore the previous level of safety.
(I could have revert these patches so as to resume used of .value()
but I didn't want to just have them get broken again.)
Differential Revision: https://reviews.llvm.org/D140340