From 5bf0f84e8133cc7c50dd5ad58ebcffb3be04d959 Mon Sep 17 00:00:00 2001 From: Anchu Rajendran 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 | 113 ++++++++++-------- flang/lib/Semantics/resolve-directives.cpp | 16 +++ 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, 175 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 26825468df9b1d..fa8c508d1434fb 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -2199,6 +2199,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(construct()) || "ENTER" >> construct(construct( parenthesized(Parser{}))) || + "EXCLUSIVE" >> construct(construct( + parenthesized(Parser{}))) || "FILTER" >> construct(construct( parenthesized(scalarIntExpr))) || "FINAL" >> construct(construct( @@ -286,6 +288,8 @@ TYPE_PARSER( "IF" >> construct(construct( parenthesized(Parser{}))) || "INBRANCH" >> construct(construct()) || + "INCLUSIVE" >> construct(construct( + parenthesized(Parser{}))) || "IS_DEVICE_PTR" >> construct(construct( parenthesized(Parser{}))) || "LASTPRIVATE" >> construct(construct( @@ -481,6 +485,7 @@ TYPE_PARSER(sourced(construct(verbatim("FLUSH"_tok), TYPE_PARSER(sourced(construct(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..9ba5a3c1288e10 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -532,62 +532,70 @@ 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(c.t)}; - const auto &beginDir{ - std::get(beginBlockDir.t)}; - if (beginDir.v == llvm::omp::Directive::OMPD_ordered) { - const auto &clauses{ - std::get(beginBlockDir.t)}; - for (const auto &clause : clauses.v) { - if (std::get_if(&clause.u)) { - eligibleSIMD = true; - break; - } - } - } - }, - [&](const parser::OpenMPSimpleStandaloneConstruct &c) { - const auto &dir{ - std::get(c.t)}; - if (dir.v == llvm::omp::Directive::OMPD_ordered) { - const auto &clauses{ - std::get(c.t)}; - for (const auto &clause : clauses.v) { - if (std::get_if(&clause.u)) { - eligibleSIMD = true; - break; - } - } - } - }, - // Allowing SIMD construct - [&](const parser::OpenMPLoopConstruct &c) { - const auto &beginLoopDir{ - std::get(c.t)}; - const auto &beginDir{ - std::get(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(c.t)}; + const auto &beginDir{ + std::get(beginBlockDir.t)}; + if (beginDir.v == llvm::omp::Directive::OMPD_ordered) { + const auto &clauses{ + std::get(beginBlockDir.t)}; + for (const auto &clause : clauses.v) { + if (std::get_if(&clause.u)) { + eligibleSIMD = true; + break; + } + } + } + }, + [&](const parser::OpenMPStandaloneConstruct &c) { + if (const auto &simpleConstruct = + std::get_if( + &c.u)) { + const auto &dir{std::get( + simpleConstruct->t)}; + if (dir.v == llvm::omp::Directive::OMPD_ordered) { + const auto &clauses{ + std::get(simpleConstruct->t)}; + for (const auto &clause : clauses.v) { + if (std::get_if(&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(c.t)}; + const auto &beginDir{ + std::get(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 +2539,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..131e2a74292426 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(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,20 @@ bool OmpAttributeVisitor::Pre( default: break; } + if (standaloneDir.v == llvm::omp::Directive::OMPD_scan) { + if ((std::get(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"> { }