In OpenMP Version 5.1, the tile and unroll directives were added. When
using these directives, it is possible to nest them within other OpenMP
Loop Constructs. This patch enables the semantics to allow for this
behaviour on these specific directives. Any nested loops will be stored
within the initial Loop Construct until reaching the DoConstruct itself.
Relevant tests have been added, and previous behaviour has been retained
with no changes.
See also, #110008
Name resolution defers the analysis of all object pointer initializers
to the end of a specification part, including the default initializers
of derived type data pointer components. This deferment allows object
pointer initializers to contain forward references to objects whose
declarations appear later.
However, this deferment has the unfortunate effect of causing NULL
default initialization of such object pointer components when they do
not appear in structure constructors that are used as default
initializers, and their default initializers are required. So handle
object pointer default initializers of components as they appear, as
before.
Folding hands complex exponentiations with constant arguments off to the
native libm, and on a least on host, this can produce spurious warnings
about division by zero and invalid arguments. Handle the case of a zero
base specially to avoid that, and also emit better warnings for the
undefined 0.**0 and (0.,0.)**0 cases. And add a test for these warnings
and the existing related ones.
check-io.cpp was missing checks for the definability of logical-valued
specifiers in INQUIRE statements (e.g. EXIST=), and therefore also not
noting the definitions of those variables. This could lead to bogus
warnings about undefined function result variables, and also to missed
errors about immutable objects appearing in those specifiers.
Fixes https://github.com/llvm/llvm-project/issues/144453.
Adds a hint to the warning message to disable a warning and updates the
tests to expect this.
Also fixes a bug in the storage of canonical spelling of error flags so
that they are not used after free.
Convert all binary calls of min/max to extremum operations, so that
extremums generated by the compiler compare equal, and user min/max
calls also compare equal.
Fixes#133646
Originally opened as #144162 but I accidentally pushed a merge in such a
way that a bunch of code owners got added to the review. This is just
rebasing the original work on main and fixing the failing tests.
flang incorrectly issues a semantic erorr when a `cycle` statement is
used inside a `target teams distribute [simd]` associated loop. This is
not prevented by the spec, therefore this PR allows such construct.
The previous approach rewrote the atomic constructs in the AST based on
the REQUIRES ATOMIC_DEFAULT_MEM_ORDER directives. The new approach
checks for incorrect uses of REQUIRED ADMO in the semantic analysis, and
applies it in lowering, eliminating the need for a separate
tree-rewriting procedure.
The message "The atomic variable x should occur exactly once among the
arguments of the top-level [...] operator" was intended to convey that
(1) an atomic variable should be an argument, and (2) it should be
exactly one of the arguments. However, the wording turned out to be
sowing confusion instead.
Rework the corresponding check, and emit an individual error message for
each problematic situation:
- "atomic variable cannot be a proper subexpression of an argument",
- "atomic variable should appear as an argument",
- "atomic variable should be exactly one of the arguments".
Fixes https://github.com/llvm/llvm-project/issues/144599
There has been a number of deprecation warnings that have been added to
Flang, however these features are only deprecated when the OpenMP
Version being used is 5.2 or later. Previously, flang did not consider
the version with the warnings so would always be emitted.
Flang now ensures warnings are emitted for the appropriate version of
OpenMP, and tests are updated to reflect this change.
I don't think DO CONCURRENT fits the definition of a Canonical Loop Nest
(OpenMP 6.0 section 6.4.1).
It is however explicitly allowed for the LOOP construct (6.0 section
13.8).
There's some obscure language in OpenMP 6.0 for the LOOP construct:
> If the collapsed loop is a DO CONCURRENT loop, neither the
> data-sharing attribute clauses nor the collapse clause may be
specified.
From the surrounding context, I think "collapsed loop" just means the
loop that the LOOP construct applies to. So I will interpret this to
mean that DO CONCURRENT can only be used with the LOOP construct if it
does not contain the COLLAPSE clause.
This also fixes a bug where the associated clause was never cleared
after it was set.
Fixes#144178
Previously we didn't push any context for SECTION and they are not
modelled with differing scopes and so goto detection couldn't tell that
GOTOs between two SECTIONs were between constructs rather than just
staying inside of the parent SECTIONS construct.
Fixes#143231
As part of OpenMP Version 5.1, support for the `indirect` clause was
added for the `declare target` directive. This clause should follow an
`enter` clause, and allows procedure calls to be done indirectly through
OpenMP.
This adds Parsing support for the clause, along with semantics checks.
Currently, lowering for the clause is not supported so a TODO message
will be outputted to the user. It also performs version checking as
`indirect` is only support in OpenMP 5.1 or greater.
See also: #110008
Recursion, both direct and indirect, prevents accurate stack size
calculation at link time for GPU device code. Restructure these
recursive (often mutually so) routines in the Fortran runtime with new
implementations based on an iterative work queue with
suspendable/resumable work tickets: Assign, Initialize, initializeClone,
Finalize, and Destroy.
Default derived type I/O is also recursive, but already disabled. It can
be added to this new framework later if the overall approach succeeds.
Note that derived type FINAL subroutine calls, defined assignments, and
defined I/O procedures all perform callbacks into user code, which may
well reenter the runtime library. This kind of recursion is not handled
by this change, although it may be possible to do so in the future using
thread-local work queues.
(Relanding this patch after reverting initial attempt due to some test
failures that needed some time to analyze and fix.)
Fixes https://github.com/llvm/llvm-project/issues/142481.
The SOURCE= expression of an ALLOCATE statement, when present and not
scalar, must conform to the shape of the allocated objects. Check this
at runtime, and return a recoverable error, or crash, when appropriate.
Fixes https://github.com/llvm/llvm-project/issues/143900.
It's possible for the module file generation code to think that it needs
to (re)generate a module file for a dependent module read from a
hermetic module file, if it defines contains a procedure imported via
renaming due to a name clash. Adjust the logic that determines whether a
module file should be written to include a check for having originated
in a module file.
Although taskgroup is a privatizing construct, because of
task_reduction clause, a new scope was not being created for it.
This could cause an extra privatization of variables when
taskgroup was lowered, because its scope would be the same as of
the parent privatizing construct.
This fixes regressions in tests 1052_0201 and 1052_0205, from
Fujitsu testsuite.
This issue didn't happen before because implicit symbols were
being created in a different way before #142154.
According to OpenMP 5.0 rules, the ACQ_REL ordering coming from a
REQUIRES directive may need to be replaced with ACQUIRE or RELEASE
depending on the directive in the ATOMIC construct. This was not done,
leading to an incorrect "memory-order" clause appearing in the generated
HLFIR.
This may need to be relaxed a bit to fully comply with later spec
versions, that will be done in a future PR.
Fixes#142404
The parser can't tell the difference between array indexing and a
substring: that has to be done in semantics once we have types.
Substrings can only be in the form string([lower]:[higher]) not
string(index) or string(lower:higher:step). I added semantic checks to
catch this for the DEPEND clause.
This patch also adds lowering for correct substrings and for complex
part references.
`SetImplicitCUDADevice` looks for `symbol.has<ObjectEntityDetails>()` to
set the device attribute before symbols inside block constructs are
converted to ObjectEntity. Fix is to move the call to
`SetImplicitCUDADevice` after those symbols are converted.
When emitting the modules on which a module depends under the
-fhermetic-module-files options, eliminate duplicates by name rather
than by symbol addresses. This way, when a dependent module is in the
symbol table more than once due to the use of a nested hermetic module,
it doesn't get emitted multiple times to the new module file.
The global name semantic check was firing in a bogus way when BIND(C)
variables are in hermetic module.
Do not raise the error if one of the symbol with the conflicting global
name is an "hermetic variant" of the other.
The parser will accept a wide variety of illegal attempts at forming an
ATOMIC construct, leaving it to the semantic analysis to diagnose any
issues. This consolidates the analysis into one place and allows us to
produce more informative diagnostics.
The parser's outcome will be parser::OpenMPAtomicConstruct object
holding the directive, parser::Body, and an optional end-directive. The
prior variety of OmpAtomicXyz classes, as well as OmpAtomicClause have
been removed. READ, WRITE, etc. are now proper clauses.
The semantic analysis consistently operates on "evaluation"
representations, mainly evaluate::Expr (as SomeExpr) and
evaluate::Assignment. The results of the semantic analysis are stored in
a mutable member of the OpenMPAtomicConstruct node. This follows a
precedent of having `typedExpr` member in parser::Expr, for example.
This allows the lowering code to avoid duplicated handling of AST nodes.
Using a BLOCK construct containing multiple statements for an ATOMIC
construct that requires multiple statements is now allowed. In fact, any
nesting of such BLOCK constructs is allowed.
This implementation will parse, and perform semantic checks for both
conditional-update and conditional-update-capture, although no MLIR will
be generated for those. Instead, a TODO error will be issues prior to
lowering.
The allowed forms of the ATOMIC construct were based on the OpenMP 6.0
spec.
Symbols that have a pre-existing DSA set in the enclosing context should
not be made shared based on them being static duration variables.
Suggested-by: Leandro Lupori <leandro.lupori@linaro.org>
---------
Signed-off-by: Kajetan Puchalski <kajetan.puchalski@arm.com>
When a derived type declares a generic procedure binding of interest to
the runtime library, such as for ASSIGNMENT(=), it overrides any binding
that might have been present for the parent type.
Fixes https://github.com/llvm/llvm-project/issues/142414.
Recursion, both direct and indirect, prevents accurate stack size
calculation at link time for GPU device code. Restructure these
recursive (often mutually so) routines in the Fortran runtime with new
implementations based on an iterative work queue with
suspendable/resumable work tickets: Assign, Initialize, initializeClone,
Finalize, and Destroy.
Default derived type I/O is also recursive, but already disabled. It can
be added to this new framework later if the overall approach succeeds.
Note that derived type FINAL subroutine calls, defined assignments, and
defined I/O procedures all perform callbacks into user code, which may
well reenter the runtime library. This kind of recursion is not handled
by this change, although it may be possible to do so in the future using
thread-local work queues.
The effects of this restructuring on CPU performance are yet to be
measured.
According to the OpenMP standard, variables with static storage duration
are predetermined as shared.
Add a check when creating implicit symbols for OpenMP to fix them
erroneously getting set to firstprivate.
Fixes llvm#140732.
---------
Signed-off-by: Kajetan Puchalski <kajetan.puchalski@arm.com>
This adds another puzzle piece for the support of OpenMP DECLARE
REDUCTION functionality.
This adds support for operators with derived types, as well as declaring
multiple different types with the same name or operator.
A new detail class for UserReductionDetials is introduced to hold the
list of types supported for a given reduction declaration.
Tests for parsing and symbol generation added.
Declare reduction is still not supported to lowering, it will generate a
"Not yet implemented" fatal error.
Fixes#141306Fixes#97241Fixes#92832Fixes#66453
---------
Co-authored-by: Mats Petersson <mats.petersson@arm.com>
If a "TASK DEPEND" clause is not given a valid task dependece type
modifier, the semantic checks for the clause will result in an ICE
because they assume that such modifiers will be present. Check whether
the modifiers are present and show an appropriate error instead of
crashing the compiler if they are not.
Fixes llvm#133678.
Signed-off-by: Kajetan Puchalski <kajetan.puchalski@arm.com>
Inaccessible procedure bindings can't be overridden, but DEFERRED
bindings must be in a non-abstract extension. We presently emit an error
for an attempt to override an inaccessible binding in this case. But
some compilers accept this usage, and since it seems safe enough, I'll
allow it with an optional warning. Codes can avoid this warning and
conform to the standard by changing the deferred bindings to be public.
For componentwise assignment in derived type intrinsic assignment, the
runtime type information's special binding table is currently populated
only with type-bound ASSIGNMENT(=) procedures that have the same derived
type for both arguments. This restriction excludes all defined
assignments for cases that cannot arise in this context, like defined
assignments from intrinsic types or incompatible derived types.
However, this restriction also excludes defined assignments from
distinct but compatible derived types, i.e. ancestors. Loosen it a
little to allow them.
Fixes https://github.com/llvm/llvm-project/issues/142151.
When a generic ASSIGNMENT(=) has elemental and non-elemental specific
procedures that match the actual arguments, the non-elemental procedure
must take precedence. We get this right for generics defined with
interface blocks, but the type-bound case fails if the non-elemental
specific takes a non-default PASS argument.
Fixes https://github.com/llvm/llvm-project/issues/141807.
DeclareSimdConstruct (and other declarative constructs) can currently
implicitly declare variables regardless of whether the source code
contains "implicit none" or not. This causes semantic analysis issues if
the implicit type does not match the declared type. To solve it, skip
implicit typing for OpenMPDeclarativeConstruct. Fixes issue #140754.
---------
Signed-off-by: Kajetan Puchalski <kajetan.puchalski@arm.com>
As part of OpenMP 5.2, the allocate directive has been deprecated in
favour of the allocators construct for Fortran when an ALLOCATE
statement follows the OpenMP allocate directive.
To enable this in flang, a warning has been added informing the user of
this. Tests to ensure this behaviour is continued are also included.
See also: #110008
Before this change, OmpShared was not always set in shared symbols.
Instead, absence of private flags was interpreted as shared DSA.
The problem was that symbols with no flags, with only a host
association, could also mean "has same DSA as in the enclosing
context". Now shared symbols behave the same as private and can be
treated the same way.
Because of the host association symbols with no flags mentioned
above, it was also incorrect to simply test the flags of a given
symbol to find out if it was private or shared. The function
GetSymbolDSA() was added to fix this. It would be better to avoid
the need of these special symbols, but this would require changes
to how symbols are collected in lowering.
Besides that, some semantic checks need to know if a DSA clause
was used or not. To avoid confusing implicit symbols with DSA
clauses a new flag was added: OmpExplicit. It is now set for all
symbols with explicitly determined data-sharing attributes.
With the changes above, AddToContextObjectWithDSA() and the symbol
to DSA map could probably be removed and the DSA could be obtained
directly from the symbol, but this was not attempted.
Some debug messages were also added, with the "omp" DEBUG_TYPE, to
make it easier to debug the creation of implicit symbols and to
visualize all associations of a given symbol.
Fixes#130533Fixes#140882
Add a visitor for OmpClause::Uniform to resolve its parameter names.
Add Symbol::Flag::OmpUniform to attach it to the resolved symbols.
Fixes issue #140741.
---------
Signed-off-by: Kajetan Puchalski <kajetan.puchalski@arm.com>
Even though the spec (version 5.2) prohibits strcuture components from
being specified in `depend` clauses, this restriction is not sensible.
This PR rectifies the issue by lifting that restriction and allowing
structure components in `depend` clauses (which is allowed by OpenMP
6.0).
The check if the arguments are variable list items was missing, leading
to a crash in lowering in some invalid situations.
This fixes the first testcase reported in
https://github.com/llvm/llvm-project/issues/141481
A dummy argument with an explicit INTEGER type of non-default kind can
be forward-referenced from a specification expression in many Fortran
compilers. Handle by adding type declaration statements to the initial
pass over a specification part's declaration constructs. Emit an
optional warning under -pedantic.
Fixes https://github.com/llvm/llvm-project/issues/140941.
When a TYPE(*) dummy argument is erroneously used as a component value
in a structure constructor, semantics crashes if the structure
constructor had been initially parsed as a potential function reference.
Clean out stale typed expressions when reanalyzing the reconstructed
parse subtree to ensure that errors are caught the next time around.