[flang-commits] [flang] [llvm] Adding parsing and semantic support for scan directive. (PR #102792)
Anchu Rajendran S via flang-commits
flang-commits at lists.llvm.org
Sun Aug 11 22:13:01 PDT 2024
https://github.com/anchuraj updated https://github.com/llvm/llvm-project/pull/102792
>From 8f042f398b9cf476a63297b3ac0004c298aaaecd Mon Sep 17 00:00:00 2001
From: Anchu Rajendran <asudhaku at amd.com>
Date: Thu, 8 Aug 2024 15:28:26 -0500
Subject: [PATCH] Adding parsing support for scan directive.
---
flang/lib/Lower/OpenMP/OpenMP.cpp | 3 +
flang/lib/Parser/openmp-parsers.cpp | 5 +
flang/lib/Parser/unparse.cpp | 3 +
flang/lib/Semantics/check-omp-structure.cpp | 114 ++++++++++--------
flang/lib/Semantics/resolve-directives.cpp | 17 +++
flang/test/Parser/OpenMP/scan.f90 | 40 ++++++
flang/test/Semantics/OpenMP/do05.f90 | 8 +-
.../test/Semantics/OpenMP/nested-barrier.f90 | 4 +-
flang/test/Semantics/OpenMP/nested-master.f90 | 2 +-
flang/test/Semantics/OpenMP/nested-simd.f90 | 34 +++---
flang/test/Semantics/OpenMP/ordered-simd.f90 | 2 +-
flang/test/Semantics/OpenMP/scan.f90 | 19 +++
llvm/include/llvm/Frontend/OpenMP/OMP.td | 2 +
13 files changed, 177 insertions(+), 76 deletions(-)
create mode 100644 flang/test/Parser/OpenMP/scan.f90
create mode 100644 flang/test/Semantics/OpenMP/scan.f90
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index bbde77c14f36a1..52cc15d4ac6946 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -2189,6 +2189,9 @@ static void genOMPDispatch(lower::AbstractConverter &converter,
case llvm::omp::Directive::OMPD_parallel:
genStandaloneParallel(converter, symTable, semaCtx, eval, loc, queue, item);
break;
+ case llvm::omp::Directive::OMPD_scan:
+ TODO(loc, "Unhandled directive " + llvm::omp::getOpenMPDirectiveName(dir));
+ break;
case llvm::omp::Directive::OMPD_section:
llvm_unreachable("genOMPDispatch: OMPD_section");
// Lowered in the enclosing genSectionsOp.
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 52789d6e5f0f6b..5951be846762ab 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -267,6 +267,8 @@ TYPE_PARSER(
construct<OmpClause>(construct<OmpClause::DynamicAllocators>()) ||
"ENTER" >> construct<OmpClause>(construct<OmpClause::Enter>(
parenthesized(Parser<OmpObjectList>{}))) ||
+ "EXCLUSIVE" >> construct<OmpClause>(construct<OmpClause::Exclusive>(
+ parenthesized(Parser<OmpObjectList>{}))) ||
"FILTER" >> construct<OmpClause>(construct<OmpClause::Filter>(
parenthesized(scalarIntExpr))) ||
"FINAL" >> construct<OmpClause>(construct<OmpClause::Final>(
@@ -286,6 +288,8 @@ TYPE_PARSER(
"IF" >> construct<OmpClause>(construct<OmpClause::If>(
parenthesized(Parser<OmpIfClause>{}))) ||
"INBRANCH" >> construct<OmpClause>(construct<OmpClause::Inbranch>()) ||
+ "INCLUSIVE" >> construct<OmpClause>(construct<OmpClause::Inclusive>(
+ parenthesized(Parser<OmpObjectList>{}))) ||
"IS_DEVICE_PTR" >> construct<OmpClause>(construct<OmpClause::IsDevicePtr>(
parenthesized(Parser<OmpObjectList>{}))) ||
"LASTPRIVATE" >> construct<OmpClause>(construct<OmpClause::Lastprivate>(
@@ -481,6 +485,7 @@ TYPE_PARSER(sourced(construct<OpenMPFlushConstruct>(verbatim("FLUSH"_tok),
TYPE_PARSER(sourced(construct<OmpSimpleStandaloneDirective>(first(
"BARRIER" >> pure(llvm::omp::Directive::OMPD_barrier),
"ORDERED" >> pure(llvm::omp::Directive::OMPD_ordered),
+ "SCAN" >> pure(llvm::omp::Directive::OMPD_scan),
"TARGET ENTER DATA" >> pure(llvm::omp::Directive::OMPD_target_enter_data),
"TARGET EXIT DATA" >> pure(llvm::omp::Directive::OMPD_target_exit_data),
"TARGET UPDATE" >> pure(llvm::omp::Directive::OMPD_target_update),
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 2511a5dda9d095..f252512a41f655 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2295,6 +2295,9 @@ class UnparseVisitor {
case llvm::omp::Directive::OMPD_barrier:
Word("BARRIER ");
break;
+ case llvm::omp::Directive::OMPD_scan:
+ Word("SCAN ");
+ break;
case llvm::omp::Directive::OMPD_taskwait:
Word("TASKWAIT ");
break;
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 50840898438c78..0116304ae5102a 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -532,62 +532,71 @@ void OmpStructureChecker::CheckSIMDNest(const parser::OpenMPConstruct &c) {
// current context yet.
// TODO: Check for declare simd regions.
bool eligibleSIMD{false};
- common::visit(Fortran::common::visitors{
- // Allow `!$OMP ORDERED SIMD`
- [&](const parser::OpenMPBlockConstruct &c) {
- const auto &beginBlockDir{
- std::get<parser::OmpBeginBlockDirective>(c.t)};
- const auto &beginDir{
- std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
- if (beginDir.v == llvm::omp::Directive::OMPD_ordered) {
- const auto &clauses{
- std::get<parser::OmpClauseList>(beginBlockDir.t)};
- for (const auto &clause : clauses.v) {
- if (std::get_if<parser::OmpClause::Simd>(&clause.u)) {
- eligibleSIMD = true;
- break;
- }
- }
- }
- },
- [&](const parser::OpenMPSimpleStandaloneConstruct &c) {
- const auto &dir{
- std::get<parser::OmpSimpleStandaloneDirective>(c.t)};
- if (dir.v == llvm::omp::Directive::OMPD_ordered) {
- const auto &clauses{
- std::get<parser::OmpClauseList>(c.t)};
- for (const auto &clause : clauses.v) {
- if (std::get_if<parser::OmpClause::Simd>(&clause.u)) {
- eligibleSIMD = true;
- break;
- }
- }
- }
- },
- // Allowing SIMD construct
- [&](const parser::OpenMPLoopConstruct &c) {
- const auto &beginLoopDir{
- std::get<parser::OmpBeginLoopDirective>(c.t)};
- const auto &beginDir{
- std::get<parser::OmpLoopDirective>(beginLoopDir.t)};
- if ((beginDir.v == llvm::omp::Directive::OMPD_simd) ||
- (beginDir.v == llvm::omp::Directive::OMPD_do_simd)) {
- eligibleSIMD = true;
- }
- },
- [&](const parser::OpenMPAtomicConstruct &c) {
- // Allow `!$OMP ATOMIC`
- eligibleSIMD = true;
- },
- [&](const auto &c) {},
- },
+ common::visit(
+ Fortran::common::visitors{
+ // Allow `!$OMP ORDERED SIMD`
+ [&](const parser::OpenMPBlockConstruct &c) {
+ const auto &beginBlockDir{
+ std::get<parser::OmpBeginBlockDirective>(c.t)};
+ const auto &beginDir{
+ std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
+ if (beginDir.v == llvm::omp::Directive::OMPD_ordered) {
+ const auto &clauses{
+ std::get<parser::OmpClauseList>(beginBlockDir.t)};
+ for (const auto &clause : clauses.v) {
+ if (std::get_if<parser::OmpClause::Simd>(&clause.u)) {
+ eligibleSIMD = true;
+ break;
+ }
+ }
+ }
+ },
+ [&](const parser::OpenMPStandaloneConstruct &c) {
+ if (const auto &simpleConstruct =
+ std::get_if<parser::OpenMPSimpleStandaloneConstruct>(
+ &c.u)) {
+ const auto &dir{std::get<parser::OmpSimpleStandaloneDirective>(
+ simpleConstruct->t)};
+ if (dir.v == llvm::omp::Directive::OMPD_ordered) {
+ const auto &clauses{
+ std::get<parser::OmpClauseList>(simpleConstruct->t)};
+ for (const auto &clause : clauses.v) {
+ if (std::get_if<parser::OmpClause::Simd>(&clause.u)) {
+ eligibleSIMD = true;
+ break;
+ }
+ }
+ } else if (dir.v == llvm::omp::Directive::OMPD_scan) {
+ eligibleSIMD = true;
+ }
+ }
+ },
+ // Allowing SIMD construct
+ [&](const parser::OpenMPLoopConstruct &c) {
+ const auto &beginLoopDir{
+ std::get<parser::OmpBeginLoopDirective>(c.t)};
+ const auto &beginDir{
+ std::get<parser::OmpLoopDirective>(beginLoopDir.t)};
+ if ((beginDir.v == llvm::omp::Directive::OMPD_simd) ||
+ (beginDir.v == llvm::omp::Directive::OMPD_parallel_do_simd) ||
+ (beginDir.v == llvm::omp::Directive::OMPD_do_simd)) {
+ eligibleSIMD = true;
+ }
+ },
+ [&](const parser::OpenMPAtomicConstruct &c) {
+ // Allow `!$OMP ATOMIC`
+ eligibleSIMD = true;
+ },
+ [&](const auto &c) {},
+ },
c.u);
if (!eligibleSIMD) {
context_.Say(parser::FindSourceLocation(c),
"The only OpenMP constructs that can be encountered during execution "
"of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, "
- "the `SIMD` construct and the `ORDERED` construct with the `SIMD` "
- "clause."_err_en_US);
+ "the `SIMD` construct, the `SCAN` construct and the `ORDERED` "
+ "construct "
+ "with the `SIMD` clause."_err_en_US);
}
}
@@ -2531,6 +2540,9 @@ void OmpStructureChecker::CheckReductionModifier(
switch (dirCtx.directive) {
case llvm::omp::Directive::OMPD_do: // worksharing-loop
case llvm::omp::Directive::OMPD_do_simd: // worksharing-loop simd
+ case llvm::omp::Directive::
+ OMPD_parallel_do_simd: // worksharing-parallel-loop
+ // simd
case llvm::omp::Directive::OMPD_simd: // "simd"
break;
default:
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index d635a7b8b7874f..c5e147a4198aa7 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1578,9 +1578,11 @@ bool OmpAttributeVisitor::Pre(
const parser::OpenMPSimpleStandaloneConstruct &x) {
const auto &standaloneDir{
std::get<parser::OmpSimpleStandaloneDirective>(x.t)};
+ const auto &parentContext{GetContextIf()};
switch (standaloneDir.v) {
case llvm::omp::Directive::OMPD_barrier:
case llvm::omp::Directive::OMPD_ordered:
+ case llvm::omp::Directive::OMPD_scan:
case llvm::omp::Directive::OMPD_target_enter_data:
case llvm::omp::Directive::OMPD_target_exit_data:
case llvm::omp::Directive::OMPD_target_update:
@@ -1591,6 +1593,21 @@ bool OmpAttributeVisitor::Pre(
default:
break;
}
+ if (standaloneDir.v == llvm::omp::Directive::OMPD_scan) {
+ if ((std::get<parser::OmpClauseList>(x.t).v.size() != 1)) {
+ context_.Say(standaloneDir.source,
+ "Exactly one of `exclusive` or `inclusive` clause is expected"_err_en_US);
+ }
+ if (!parentContext ||
+ (llvm::omp::getDirectiveAssociation(parentContext->directive) !=
+ llvm::omp::Association::Loop)) {
+ context_.Say(standaloneDir.source,
+ "Orphaned `omp scan` directives are prohibited; perhaps you forgot "
+ "to "
+ "enclose the directive in to a worksharing loop, a worksharing loop "
+ "simd or a simd directive."_err_en_US);
+ }
+ }
ClearDataSharingAttributeObjects();
return true;
}
diff --git a/flang/test/Parser/OpenMP/scan.f90 b/flang/test/Parser/OpenMP/scan.f90
new file mode 100644
index 00000000000000..a6e23ac9404882
--- /dev/null
+++ b/flang/test/Parser/OpenMP/scan.f90
@@ -0,0 +1,40 @@
+! RUN: %flang_fc1 -fdebug-unparse -fopenmp %s | FileCheck --ignore-case %s
+! RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp %s | FileCheck --check-prefix="PARSE-TREE" %s
+
+! Check for parsing scan directive
+subroutine test_scan_inclusive()
+ implicit none
+ integer, parameter :: n = 100
+ integer a(n), b(n)
+ integer x, k
+
+ ! initialization
+ x = 0
+ do k = 1, n
+ a(k) = k
+ end do
+
+ ! a(k) is included in the computation of producing results in b(k)
+ !$omp parallel do simd reduction(inscan,+: x)
+ do k = 1, n
+ x = x + a(k)
+ !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPSimpleStandaloneConstruct
+ !PARSE-TREE-NEXT: OmpSimpleStandaloneDirective -> llvm::omp::Directive = scan
+ !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Inclusive -> OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
+ !CHECK: !$omp scan inclusive(x)
+ !$omp scan inclusive(x)
+ b(k) = x
+ end do
+
+ ! a(k) is not included in the computation of producing results in b(k)
+ !$omp parallel do simd reduction(inscan,+: x)
+ do k = 1, n
+ b(k) = x
+ !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPSimpleStandaloneConstruct
+ !PARSE-TREE-NEXT: OmpSimpleStandaloneDirective -> llvm::omp::Directive = scan
+ !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Exclusive -> OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
+ !CHECK: !$omp scan exclusive(x)
+ !$omp scan exclusive(x)
+ x = x + a(k)
+ end do
+end subroutine
diff --git a/flang/test/Semantics/OpenMP/do05.f90 b/flang/test/Semantics/OpenMP/do05.f90
index c0f240db57b65b..24844f9fe4f62a 100644
--- a/flang/test/Semantics/OpenMP/do05.f90
+++ b/flang/test/Semantics/OpenMP/do05.f90
@@ -39,7 +39,7 @@ program omp_do
if( i == 5 ) then
cycle
end if
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
!$omp single
do j=1,10
@@ -70,7 +70,7 @@ program omp_do
if( i == 3 ) then
cycle
end if
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
!$omp single
do j=1,10
@@ -93,7 +93,7 @@ program omp_do
!$omp target parallel do simd
do i=1,10
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
!$omp single
do j=1,10
@@ -116,7 +116,7 @@ program omp_do
!$omp target teams distribute parallel do simd
do i=1,10
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
!$omp single
do j=1,10
diff --git a/flang/test/Semantics/OpenMP/nested-barrier.f90 b/flang/test/Semantics/OpenMP/nested-barrier.f90
index aae283229e330d..ed13c98539c93c 100644
--- a/flang/test/Semantics/OpenMP/nested-barrier.f90
+++ b/flang/test/Semantics/OpenMP/nested-barrier.f90
@@ -17,7 +17,7 @@ program omp_nest_barrier
!$omp do simd
do i = 1, 10
k = k + 1
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region.
!$omp barrier
j = j -1
@@ -34,7 +34,7 @@ program omp_nest_barrier
!$omp parallel do simd
do i = 1, 10
k = k + 1
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region.
!$omp barrier
j = j -1
diff --git a/flang/test/Semantics/OpenMP/nested-master.f90 b/flang/test/Semantics/OpenMP/nested-master.f90
index 069de67cafae28..0a5118bb947550 100644
--- a/flang/test/Semantics/OpenMP/nested-master.f90
+++ b/flang/test/Semantics/OpenMP/nested-master.f90
@@ -64,7 +64,7 @@ program omp_nest_master
do i = 1, 10
k = k + 1
!WARNING: OpenMP directive 'master' has been deprecated, please use 'masked' instead.
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region.
!$omp master
j = j -1
diff --git a/flang/test/Semantics/OpenMP/nested-simd.f90 b/flang/test/Semantics/OpenMP/nested-simd.f90
index 4149b6d97e9dc7..c9fb90cdeceb25 100644
--- a/flang/test/Semantics/OpenMP/nested-simd.f90
+++ b/flang/test/Semantics/OpenMP/nested-simd.f90
@@ -40,7 +40,7 @@ SUBROUTINE NESTED_BAD(N)
!$OMP ORDERED SIMD
DO J = 1,N
print *, "Hi"
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region
!$omp teams
DO K = 1,N
@@ -58,25 +58,25 @@ SUBROUTINE NESTED_BAD(N)
!$OMP ATOMIC
K = K + 1
IF (I <= 10) THEN
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!$omp task
do J = 1, N
K = 2
end do
!$omp end task
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!$omp target
do J = 1, N
K = 2
end do
!$omp end target
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!$OMP DO
DO J = 1,N
A(J) = J
END DO
!$OMP END DO
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!$OMP PARALLEL DO
DO J = 1,N
A(J) = J
@@ -91,26 +91,26 @@ SUBROUTINE NESTED_BAD(N)
!$OMP ATOMIC
K = K + 1
IF (I <= 10) THEN
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!$omp task
do J = 1, N
K = 2
end do
!$omp end task
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!$omp target
do J = 1, N
K = 2
end do
!$omp end target
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
!$OMP DO
DO J = 1,N
A(J) = J
END DO
!$OMP END DO
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!$OMP PARALLEL DO
DO J = 1,N
A(J) = J
@@ -125,26 +125,26 @@ SUBROUTINE NESTED_BAD(N)
!$OMP ATOMIC
K = K + 1
IF (I <= 10) THEN
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!$omp task
do J = 1, N
K = 2
end do
!$omp end task
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!$omp target
do J = 1, N
K = 2
end do
!$omp end target
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
!$OMP DO
DO J = 1,N
A(J) = J
END DO
!$OMP END DO
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!$OMP PARALLEL DO
DO J = 1,N
A(J) = J
@@ -159,25 +159,25 @@ SUBROUTINE NESTED_BAD(N)
!$OMP ATOMIC
K = K + 1
IF (I <= 10) THEN
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!$omp task
do J = 1, N
K = 2
end do
!$omp end task
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!$omp target
do J = 1, N
K = 2
end do
!$omp end target
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!$OMP DO
DO J = 1,N
A(J) = J
END DO
!$OMP END DO
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!$OMP PARALLEL DO
DO J = 1,N
A(J) = J
diff --git a/flang/test/Semantics/OpenMP/ordered-simd.f90 b/flang/test/Semantics/OpenMP/ordered-simd.f90
index ed52b759491002..0df0471f3db60e 100644
--- a/flang/test/Semantics/OpenMP/ordered-simd.f90
+++ b/flang/test/Semantics/OpenMP/ordered-simd.f90
@@ -25,7 +25,7 @@ SUBROUTINE ORDERED_BAD(N)
!$OMP DO SIMD
DO I = 1,N
IF (I <= 10) THEN
- !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
!ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
!$OMP ORDERED
CALL WORK(I)
diff --git a/flang/test/Semantics/OpenMP/scan.f90 b/flang/test/Semantics/OpenMP/scan.f90
new file mode 100644
index 00000000000000..76a0379dfec55c
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/scan.f90
@@ -0,0 +1,19 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+
+subroutine test_scan()
+ integer x, k
+
+ !ERROR: Orphaned `omp scan` directives are prohibited; perhaps you forgot to enclose the directive in to a worksharing loop, a worksharing loop simd or a simd directive.
+ !$omp scan inclusive(x)
+ !$omp parallel do simd reduction(inscan,+: x)
+ do k = 1, n
+ !ERROR: UNTIED clause is not allowed on the SCAN directive
+ !$omp scan untied
+ end do
+
+ !$omp parallel do simd reduction(inscan,+: x)
+ do k = 1, n
+ !ERROR: Exactly one of `exclusive` or `inclusive` clause is expected
+ !$omp scan
+ end do
+end subroutine
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index 2cbcbd883fb2e3..6a96fe1d82abef 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -156,6 +156,7 @@ def OMPC_Enter : Clause<"enter"> {
}
def OMPC_Exclusive : Clause<"exclusive"> {
let clangClass = "OMPExclusiveClause";
+ let flangClass = "OmpObjectList";
}
def OMPC_Fail : Clause<"fail"> {
let clangClass = "OMPFailClause";
@@ -213,6 +214,7 @@ def OMPC_Inbranch : Clause<"inbranch"> {
}
def OMPC_Inclusive : Clause<"inclusive"> {
let clangClass = "OMPInclusiveClause";
+ let flangClass = "OmpObjectList";
}
def OMPC_Indirect : Clause<"indirect"> {
}
More information about the flang-commits
mailing list