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}; @@ -250,6 +254,8 @@ 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 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); + } + else 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); @@ -640,6 +646,47 @@ 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)}) { + for (const auto &s : sizeClause->v) { + //const auto *type { + const auto u = GetIntValue(s); + 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-multisize.f90 b/flang/test/Parser/omp-tile-multisize.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Parser/omp-tile-multisize.f90 @@ -0,0 +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 + +subroutine openmp_tiles(x, y, z) + +integer, intent(inout)::x, y, z + +!CHECK : !$omp tile sizes +!$omp tile sizes(2, 2, 2) +!CHECK : do +do x = 1, 100 +do y = 1, 100 +do z = 1, 100 + call F1() +!CHECK: end do +end do +end do +end do +!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,17 @@ +!RUN: % python %S/../test_errors.py %s %flang -fopenmp +!OpenMP Version 5.1 +!2.11.9.1 tile Cconstruct + +program omp_dotile + integer::i, j, k,z + !ERROR: The parameter value in the Partial clause must be greater than one + !$omp tile sizes(2, -2, 2) + do i = 1,100 + do j = 1,100 + do k = 1,100 + print *,"hello" + end do + end do + 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,13 @@ +!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 parameter value in the Partial clause must be greater than one + !$omp unroll partial(-1) + do j = 1,10 + print *,"hello" + end do + !$omp end unroll +end program omp_doUnroll