16 Commits

Author SHA1 Message Date
Michael Kruse
38853a0146 [flang][OpenMP] MSVC buildbot fix
PR #153488 caused the msvc build (https://lab.llvm.org/buildbot/#/builders/166/builds/1397) to fail:
```
..\llvm-project\flang\include\flang/Evaluate/rewrite.h(78): error C2668: 'Fortran::evaluate::rewrite::Identity::operator ()': ambiguous call to overloaded function
..\llvm-project\flang\include\flang/Evaluate/rewrite.h(43): note: could be 'Fortran::evaluate::Expr<Fortran::evaluate::SomeType> Fortran::evaluate::rewrite::Identity::operator ()<Fortran::evaluate::SomeType,S>(Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &&,const U &)'
        with
        [
            S=Fortran::evaluate::value::Integer<128,true,32,unsigned int,unsigned __int64,128>,
            U=Fortran::evaluate::value::Integer<128,true,32,unsigned int,unsigned __int64,128>
        ]
..\llvm-project\flang\lib\Semantics\check-omp-atomic.cpp(174): note: or       'Fortran::evaluate::Expr<Fortran::evaluate::SomeType> Fortran::semantics::ReassocRewriter::operator ()<Fortran::evaluate::SomeType,S,void>(Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &&,const U &,Fortran::semantics::ReassocRewriter::NonIntegralTag)'
        with
        [
            S=Fortran::evaluate::value::Integer<128,true,32,unsigned int,unsigned __int64,128>,
            U=Fortran::evaluate::value::Integer<128,true,32,unsigned int,unsigned __int64,128>
        ]
..\llvm-project\flang\include\flang/Evaluate/rewrite.h(78): note: while trying to match the argument list '(Fortran::evaluate::Expr<Fortran::evaluate::SomeType>, const S)'
        with
        [
            S=Fortran::evaluate::value::Integer<128,true,32,unsigned int,unsigned __int64,128>
        ]
..\llvm-project\flang\include\flang/Evaluate/rewrite.h(78): note: the template instantiation context (the oldest one first) is
..\llvm-project\flang\lib\Semantics\check-omp-atomic.cpp(814): note: see reference to function template instantiation 'U Fortran::evaluate::rewrite::Mutator<Fortran::semantics::ReassocRewriter>::operator ()<const Fortran::evaluate::Expr<Fortran::evaluate::SomeType>&,Fortran::evaluate::Expr<Fortran::evaluate::SomeType>>(T)' being compiled
        with
        [
            U=Fortran::evaluate::Expr<Fortran::evaluate::SomeType>,
            T=const Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &
        ]
```

The reason is that there is an ambiguity between operator() of
ReassocRewriter itself and operator() of the base class `Identity` through
`using Id::operator();`. By the C++ specification, method declarations
in ReassocRewriter hide methods with the same signature from a using
declaration, but this does not apply to
```
evaluate::Expr<T> operator()(..., NonIntegralTag = {})
```
which has a different signature due to an additional tag parameter.
Since it has a default value, it is ambiguous with operator() without
tag parameter.

GCC and Clang both accept this, but in my understanding MSVC is correct
here.

Since the overloads of ReassocRewriter cover all cases (integral and
non-integral), removing the using declaration to avoid the ambiguity.
2025-08-14 12:30:59 +02:00
Krzysztof Parzyszek
1e7772abcb
[flang][OpenMP] Reassociate ATOMIC update expressions (#153488)
An atomic update expression of form
  x = x + a + b
is technically illegal, since the right-hand side is parsed as (x+a)+b,
and the atomic variable x should be an argument to the top-level +. When
the type of x is integer, the result of (x+a)+b is guaranteed to be the
same as x+(a+b), so instead of reporting an error, the compiler can
treat (x+a)+b as x+(a+b).

This PR implements this kind of reassociation for integral types, and
for the two arithmetic associative/commutative operators: + and *.

Reinstate PR153098 one more time with fixes for the issues that came up:
- unused variable "lsrc",
- use of ‘outer1’ before deduction of ‘auto’.
2025-08-13 15:53:59 -05:00
Krzysztof Parzyszek
bb6f16ecd7 Revert "[flang][OpenMP] Reassociate ATOMIC update expressions (#153450)"
This reverts commit 7e125b9892f26d2028c3570f537e5a26f8c94447.

The fixes helped gcc-8, but not 7.5.
2025-08-13 12:17:13 -05:00
Krzysztof Parzyszek
7e125b9892
[flang][OpenMP] Reassociate ATOMIC update expressions (#153450)
An atomic update expression of form
  x = x + a + b
is technically illegal, since the right-hand side is parsed as (x+a)+b,
and the atomic variable x should be an argument to the top-level +. When
the type of x is integer, the result of (x+a)+b is guaranteed to be the
same as x+(a+b), so instead of reporting an error, the compiler can
treat (x+a)+b as x+(a+b).

This PR implements this kind of reassociation for integral types, and
for the two arithmetic associative/commutative operators: + and *.

Reinstate PR153098 with fixes for the issues that came up:
- unused variable "lsrc",
- use of ‘outer1’ before deduction of ‘auto’.
2025-08-13 12:00:05 -05:00
Krzysztof Parzyszek
6b5c38dbbb Revert "[flang][OpenMP] Reassociate ATOMIC update expressions (#153098)"
This reverts commit 4f6ae2af3563a7eefbe4179eabe10ef5898a5963.

This PR causes build breaks with older versions of GCC.
2025-08-13 10:27:53 -05:00
Krzysztof Parzyszek
ed2fa6fd89 Revert "[flang][OpenMP] Fix unused variable warning (#153409)"
This reverts commit 6b20b16b2f796b01bc5c3d5d8013a8e65b40080a.

This patch depends on PR153098 which is the one being reverted.
2025-08-13 10:27:53 -05:00
Krzysztof Parzyszek
6b20b16b2f
[flang][OpenMP] Fix unused variable warning (#153409) 2025-08-13 08:59:20 -05:00
Krzysztof Parzyszek
4f6ae2af35
[flang][OpenMP] Reassociate ATOMIC update expressions (#153098)
An atomic update expression of form
  x = x + a + b
is technically illegal, since the right-hand side is parsed as (x+a)+b,
and the atomic variable x should be an argument to the top-level +. When
the type of x is integer, the result of (x+a)+b is guaranteed to be the
same as x+(a+b), so instead of reporting an error, the compiler can
treat (x+a)+b as x+(a+b).

This PR implements this kind of reassociation for integral types, and
for the two arithmetic associative/commutative operators: + and *.
2025-08-13 08:07:11 -05:00
Krzysztof Parzyszek
4b7f3806f6
[flang][OpenMP] Move rewriting of min/max from Lower to Semantics (#153038)
There semantic analysis of the ATOMIC construct will require additional
rewriting (reassociation of certain expressions for user convenience),
and that will be driven by diagnoses made in the semantic checks.

While the rewriting of min/max is not required to be done in semantic
analysis, moving it there will make all rewriting for ATOMIC construct
be located in a single location.
2025-08-12 12:13:50 -05:00
Krzysztof Parzyszek
ea14ee4464
[flang][OpenMP] Refactor creating atomic analysis, NFC (#153036)
Turn it into a class that combines the information and generates the
analysis instead of having independent functions do it.
2025-08-11 12:20:51 -05:00
Krzysztof Parzyszek
e368b5343d
[flang][OpenMP] Make OpenMPCriticalConstruct follow block structure (#152007)
This allows not having the END CRITICAL directive in certain situations.
Update semantic checks and symbol resolution.
2025-08-07 08:10:25 -05:00
Connector Switch
8b7f81f2de
[NFC] Fix assignment typo. (#151864) 2025-08-03 22:32:00 +08:00
Krzysztof Parzyszek
6533ad04ed
[flang][OpenMP] Make all block constructs share the same structure (#150956)
The structure is
- OmpBeginDirective (aka OmpDirectiveSpecification)
- Block
- optional<OmpEndDirective> (aka optional<OmpDirectiveSpecification>)

The OmpBeginDirective and OmpEndDirective are effectively different
names for OmpDirectiveSpecification. They exist to allow the semantic
analyses to distinguish between the beginning and the ending of a block
construct without maintaining additional context.

The actual changes are in the parser: parse-tree.h and openmp-parser.cpp
in particular. The rest is simply changing the way the directive/clause
information is accessed (typically for the simpler).

All standalone and block constructs now use OmpDirectiveSpecification to
store the directive/clause information.
2025-08-01 07:52:59 -05:00
Andre Kuhlenschmidt
062b22e462
[flang][openacc] Add semantic checks for atomic constructs (#149579)
An error report of the following code generating non-atomic code led us
to realize there are missing checks in the OpenACC atomics code. Add
some of those checks for atomic and sketch how the rest of the code
should proceed in checking the rest of the properties. The following
cases are all reported as errors.
```fortran
! Originally reported error!
!$acc atomic capture
a = b
c = b
!$acc end atomic capture
! Other ambiguous, but related errors!
!$acc atomic capture
x = i
i = x
!$acc end atomic capture
!$acc atomic capture
a = b
b = b
!$acc end atomic capture
!$acc atomic capture
a = b
a = c
!$acc end atomic capture
```
2025-07-30 08:13:07 -07:00
Krzysztof Parzyszek
638943b27e
[flang][OpenMP] Convert AST node for ALLOCATORS to use Block as body (#148005)
The ALLOCATORS construct is one of the few constructs that require a
special form of the associated block.
Convert the AST node to use OmpDirectiveSpecification for the directive
and the optional end directive, and to use parser::Block as the body:
the form of the block is checked in the semantic checks (with a more
meaningful message).
2025-07-11 06:45:11 -05:00
Krzysztof Parzyszek
ba116a8bed
[flang][OpenMP] Split check-omp-structure.cpp into smaller files, NFC (#146359)
Create these new files in flang/lib/Semantics:
  openmp-utils.cpp/.h         - Common utilities
  check-omp-atomic.cpp        - Atomic-related checks
  check-omp-loop.cpp          - Loop constructs/clauses
  check-omp-metadirective.cpp - Metadirective-related checks

Update lists of included headers, std in particular.

---------

Co-authored-by: Jack Styles <jack.styles@arm.com>
2025-07-01 11:12:00 -05:00