diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -281,8 +281,8 @@ "SIMD"_id >> construct(construct()) || "SIMDLEN" >> construct(construct( parenthesized(scalarIntConstantExpr))) || - "SIZES" >> construct(construct( - parenthesized(nonemptyList(scalarIntExpr)))) || + "SIZES" >> construct( + construct(parenthesized(scalarIntExpr))) || "THREADS" >> construct(construct()) || "THREAD_LIMIT" >> construct(construct( parenthesized(scalarIntExpr))) || diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h --- a/flang/lib/Semantics/check-omp-structure.h +++ b/flang/lib/Semantics/check-omp-structure.h @@ -60,13 +60,16 @@ Directive::OMPD_parallel_workshare, Directive::OMPD_parallel_sections, Directive::OMPD_sections, Directive::OMPD_single} | doSet}; -static OmpDirectiveSet taskloopSet{ - Directive::OMPD_taskloop, Directive::OMPD_taskloop_simd}; +static OmpDirectiveSet taskloopSet{Directive::OMPD_taskloop, + Directive::OMPD_taskloop_simd, Directive::OMPD_tile, + Directive::OMPD_unroll}; static OmpDirectiveSet targetSet{Directive::OMPD_target, Directive::OMPD_target_parallel, Directive::OMPD_target_parallel_do, Directive::OMPD_target_parallel_do_simd, Directive::OMPD_target_simd, Directive::OMPD_target_teams, Directive::OMPD_target_teams_distribute, - Directive::OMPD_target_teams_distribute_simd}; + Directive::OMPD_target_teams_distribute_simd, Directive::OMPD_tile, + OMPD_unroll}; +static OmpDirectiveSet tileSet{Directive::OMPD_tile}; static OmpDirectiveSet simdSet{Directive::OMPD_distribute_parallel_do_simd, Directive::OMPD_distribute_simd, Directive::OMPD_parallel_do_simd, Directive::OMPD_do_simd, Directive::OMPD_simd, @@ -85,6 +88,7 @@ Directive::OMPD_teams_distribute_simd}; static OmpDirectiveSet taskGeneratingSet{ OmpDirectiveSet{Directive::OMPD_task} | taskloopSet}; +static OmpDirectiveSet unrollSet{Directive::OMPD_unroll}; static OmpDirectiveSet nestedOrderedErrSet{Directive::OMPD_critical, Directive::OMPD_ordered, Directive::OMPD_atomic, Directive::OMPD_task, Directive::OMPD_taskloop}; @@ -200,6 +204,10 @@ void HasInvalidTeamsNesting( const llvm::omp::Directive &dir, const parser::CharBlock &source); void HasInvalidDistributeNesting(const parser::OpenMPLoopConstruct &x); + bool HasInvalidTileNesting( + const llvm::omp::Directive &dir, const parser::CharBlock &source); + bool HasInvalidUnrollNesting( + const llvm::omp::Directive &dir, const parser::CharBlock &source); // specific clause related bool ScheduleModifierHasType(const parser::OmpScheduleClause &, const parser::OmpScheduleModifierType::ModType &); @@ -250,6 +258,10 @@ const parser::DefinedOperator::IntrinsicOperator &); void CheckReductionTypeList(const parser::OmpClause::Reduction &); void CheckMasterNesting(const parser::OpenMPBlockConstruct &x); + void CheckTileConstruct(const parser::OpenMPLoopConstruct &x); + void CheckUnrollConstruct(const parser::OpenMPLoopConstruct &x); + // void CheckTheRectangleTileNesting(const parser::OpenMPBlockConstruct &x); + // void CheckThePerfectNesting(const parser::OpenMPBlockConstruct &x); void ChecksOnOrderedAsBlock(); void CheckBarrierNesting(const parser::OpenMPSimpleStandaloneConstruct &x); void ChecksOnOrderedAsStandalone(); diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -376,7 +376,6 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) { const auto &beginLoopDir{std::get(x.t)}; const auto &beginDir{std::get(beginLoopDir.t)}; - // check matching, End directive is optional if (const auto &endLoopDir{ std::get>(x.t)}) { @@ -420,6 +419,13 @@ llvm::omp::teamSet.test(GetContextParent().directive)) { HasInvalidTeamsNesting(beginDir.v, beginDir.source); } + if (beginDir.v == llvm::omp::Directive::OMPD_tile) { + CheckTileConstruct(x); + } + if (beginDir.v == llvm::omp::Directive::OMPD_unroll) { + CheckUnrollConstruct(x); + } + if ((beginDir.v == llvm::omp::Directive::OMPD_distribute_parallel_do_simd) || (beginDir.v == llvm::omp::Directive::OMPD_distribute_simd)) { CheckDistLinear(x); @@ -621,6 +627,7 @@ if (const auto *orderedClause{ std::get_if(&clause.u)}) { if (const auto v{GetIntValue(orderedClause->v)}) { + orderedLevel = *v; } } @@ -640,6 +647,44 @@ parser::Walk(x, ompCycleChecker); } +void OmpStructureChecker::CheckTileConstruct( + const parser::OpenMPLoopConstruct &x) { + + const auto &beginLoopDir{std::get(x.t)}; + const auto &clauseList{std::get(beginLoopDir.t)}; + + for (const auto &clause : clauseList.v) { + if (const auto *sizeClause{ + std::get_if(&clause.u)}) { + const auto u = GetIntValue(sizeClause->v); + if (*u < 0) { + context_.Say(clause.source, + "The parameter value of the Size clause must be greater than " + "zero "_err_en_US); + } + } + } +} + +void OmpStructureChecker::CheckUnrollConstruct( + const parser::OpenMPLoopConstruct &x) { + + const auto &beginLoopDir{std::get(x.t)}; + const auto &clauseList{std::get(beginLoopDir.t)}; + + for (const auto &clause : clauseList.v) { + if (const auto *sizeClause{ + std::get_if(&clause.u)}) { + const auto u = GetIntValue(sizeClause->v); + if (*u < 1) { + context_.Say(clause.source, + "The parameter value of the Partial clause must be greater than " + "one "_err_en_US); + } + } + } +} + void OmpStructureChecker::CheckDistLinear( const parser::OpenMPLoopConstruct &x) { diff --git a/flang/test/Parser/omp-tile-size.f90 b/flang/test/Parser/omp-tile-size.f90 --- a/flang/test/Parser/omp-tile-size.f90 +++ b/flang/test/Parser/omp-tile-size.f90 @@ -1,23 +1,29 @@ -! 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 +!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 -subroutine openmp_tiles(x) + subroutine + openmp_tiles(x) - integer, intent(inout)::x + integer, + intent(inout)::x -!CHECK: !$omp tile sizes -!$omp tile sizes(2) -!CHECK: do - do x = 1, 100 - call F1() -!CHECK: end do - end do -!CHECK: !$omp end tile -!$omp end tile + !CHECK : !$omp tile sizes !$omp tile sizes(2) !CHECK : do do x = 1, + 100 + call F1() !CHECK : end do end do -!PARSE-TREE: OpenMPConstruct -> OpenMPLoopConstruct -!PARSE-TREE: OmpBeginLoopDirective -!PARSE-TREE: OmpLoopDirective -> llvm::omp::Directive = tile -!PARSE-TREE: OmpClauseList -> OmpClause -> Sizes -> Scalar -> Integer -> Expr = '2_4' -END subroutine openmp_tiles + !CHECK : !$omp end tile !$omp end tile + + !PARSE + - + TREE + : OpenMPConstruct->OpenMPLoopConstruct + !PARSE - TREE : OmpBeginLoopDirective !PARSE + - + TREE + : OmpLoopDirective->llvm::omp::Directive = tile !PARSE + - TREE : OmpClauseList->OmpClause->Sizes->Scalar->Integer->Expr = '2_4' END + subroutine openmp_tiles diff --git a/flang/test/Semantics/OpenMP/omp-do-tile.f90 b/flang/test/Semantics/OpenMP/omp-do-tile.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/OpenMP/omp-do-tile.f90 @@ -0,0 +1,13 @@ +!RUN : % python % S /../ test_errors.py % s % flang -fopenmp +!OpenMP Version 5.1 !2.11.9.1 tile Cconstruct + +program omp_doTile + integer::j + !ERROR: The value of the parameter in the size clause must + !be greater than 0 + !$omp tile sizes(-1) + do j = 1,10 + print *, "hello" + end do + !$omp end tile +end program omp_doTile diff --git a/flang/test/Semantics/OpenMP/omp-do-unroll.f90 b/flang/test/Semantics/OpenMP/omp-do-unroll.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/OpenMP/omp-do-unroll.f90 @@ -0,0 +1,12 @@ +!RUN : % python % S /../ test_errors.py % s % flang -fopenmp +!OpenMP Version 5.1 !2.11.9.2 unroll Cconstruct + +program omp_doUnroll + integer::j + !ERROR: The value of the parameter in the partial clause must be greater than 0 + !$omp unroll partial(-1) + do j = 1,10 + print *,"hello" + end do + !$omp end unroll +end program omp_doUnroll diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -70,7 +70,6 @@ def OMPC_Sizes: Clause<"sizes"> { let clangClass = "OMPSizesClause"; let flangClass = "ScalarIntExpr"; - let isValueList = true; } def OMPC_Full: Clause<"full"> { let clangClass = "OMPFullClause";