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/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";