diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -305,6 +305,12 @@ } void Post(const parser::Name &); + const parser::OmpClause *associatedClause{nullptr}; + void SetAssociatedClause(const parser::OmpClause &c) { + associatedClause = &c; + } + const parser::OmpClause *GetAssociatedClause() { return associatedClause; } + private: std::int64_t GetAssociatedLoopLevelFromClauses(const parser::OmpClauseList &); @@ -344,7 +350,8 @@ } // Predetermined DSA rules - void PrivatizeAssociatedLoopIndex(const parser::OpenMPLoopConstruct &); + void PrivatizeAssociatedLoopIndexAndCheckLoopLevel( + const parser::OpenMPLoopConstruct &); void ResolveSeqLoopIndexInParallelOrTaskConstruct(const parser::Name &); void ResolveOmpObjectList(const parser::OmpObjectList &, Symbol::Flag); @@ -362,6 +369,8 @@ void CheckDataCopyingClause( const parser::Name &, const Symbol &, Symbol::Flag); + + void CheckAssocLoopLevel(std::int64_t level, const parser::OmpClause *clause); }; template @@ -777,7 +786,7 @@ } ClearDataSharingAttributeObjects(); SetContextAssociatedLoopLevel(GetAssociatedLoopLevelFromClauses(clauseList)); - PrivatizeAssociatedLoopIndex(x); + PrivatizeAssociatedLoopIndexAndCheckLoopLevel(x); return true; } @@ -824,24 +833,32 @@ const parser::OmpClauseList &x) { std::int64_t orderedLevel{0}; std::int64_t collapseLevel{0}; + + const parser::OmpClause *ordClause{nullptr}; + const parser::OmpClause *collClause{nullptr}; + for (const auto &clause : x.v) { if (const auto *orderedClause{ std::get_if(&clause.u)}) { if (const auto v{EvaluateInt64(context_, orderedClause->v)}) { orderedLevel = *v; } + ordClause = &clause; } if (const auto *collapseClause{ std::get_if(&clause.u)}) { if (const auto v{EvaluateInt64(context_, collapseClause->v)}) { collapseLevel = *v; } + collClause = &clause; } } if (orderedLevel && (!collapseLevel || orderedLevel >= collapseLevel)) { + SetAssociatedClause(*ordClause); return orderedLevel; } else if (!orderedLevel && collapseLevel) { + SetAssociatedClause(*collClause); return collapseLevel; } // orderedLevel < collapseLevel is an error handled in structural checks return 1; // default is outermost loop @@ -855,10 +872,7 @@ // increment of the associated do-loop. // - The loop iteration variables in the associated do-loops of a simd // construct with multiple associated do-loops are lastprivate. -// -// TODO: revisit after semantics checks are completed for do-loop association of -// collapse and ordered -void OmpAttributeVisitor::PrivatizeAssociatedLoopIndex( +void OmpAttributeVisitor::PrivatizeAssociatedLoopIndexAndCheckLoopLevel( const parser::OpenMPLoopConstruct &x) { std::int64_t level{GetContext().associatedLoopLevel}; if (level <= 0) { @@ -887,7 +901,16 @@ const auto it{block.begin()}; loop = it != block.end() ? GetDoConstructIf(*it) : nullptr; } - CHECK(level == 0); + CheckAssocLoopLevel(level, GetAssociatedClause()); +} +void OmpAttributeVisitor::CheckAssocLoopLevel( + std::int64_t level, const parser::OmpClause *clause) { + if (clause && level != 0) { + context_.Say(clause->source, + "The value of the parameter in the COLLAPSE or ORDERED clause must" + " not be larger than the number of nested loops" + " following the construct."_err_en_US); + } } bool OmpAttributeVisitor::Pre(const parser::OpenMPSectionsConstruct &x) { diff --git a/flang/test/Semantics/omp-do-collapse-positivecases.f90 b/flang/test/Semantics/omp-do-collapse-positivecases.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/omp-do-collapse-positivecases.f90 @@ -0,0 +1,36 @@ +!RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.7.1 Collapse Clause Positive cases + +!DEF: /omp_docollapse MainProgram +program omp_docollapse + !DEF: /omp_docollapse/i ObjectEntity INTEGER(4) + !DEF: /omp_docollapse/j ObjectEntity INTEGER(4) + !DEF: /omp_docollapse/k ObjectEntity INTEGER(4) + integer i, j, k + !$omp do collapse(2) + !DEF: /omp_docollapse/Block1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /omp_docollapse/Block1/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do j=1,10 + !REF: /omp_docollapse/k + do k=1,10 + print *, "hello" + end do + end do + end do + !$omp end do + + !REF: /omp_docollapse/i + do i=1,10 + !$omp do collapse(2) + !DEF: /omp_docollapse/Block1/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do j=1,10 + !DEF: /omp_docollapse/Block1/k (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do k=1,10 + print *, "hello" + end do + end do + !$omp end do + end do +end program omp_docollapse diff --git a/flang/test/Semantics/omp-do-collapse.f90 b/flang/test/Semantics/omp-do-collapse.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/omp-do-collapse.f90 @@ -0,0 +1,26 @@ +!RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.7.1 Collapse Clause +program omp_doCollapse + integer:: i,j + !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct. + !$omp do collapse(3) + do i = 1,10 + do j = 1, 10 + print *, "hello" + end do + end do + !$omp end do + + do i = 1,10 + do j = 1, 10 + !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct. + !$omp do collapse(2) + do k = 1, 10 + print *, "hello" + end do + !$omp end do + end do + end do +end program omp_doCollapse + diff --git a/flang/test/Semantics/omp-do-ordered-positivecases.f90 b/flang/test/Semantics/omp-do-ordered-positivecases.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/omp-do-ordered-positivecases.f90 @@ -0,0 +1,67 @@ +!RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.7.1 Ordered Clause positive cases. + +!DEF: /omp_doordered MainProgram +program omp_doordered + !DEF: /omp_doordered/i ObjectEntity INTEGER(4) + !DEF: /omp_doordered/j ObjectEntity INTEGER(4) + integer i, j + !$omp do ordered(2) + !DEF: /omp_doordered/Block1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /omp_doordered/Block1/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do j=1,10 + print *, "hello" + end do + end do + !$omp end do + + !REF: /omp_doordered/i + do i=1,10 + !REF: /omp_doordered/j + do j=1,10 + !$omp do ordered(1) + !DEF: /omp_doordered/Block2/k (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do k=1,10 + print *, "hello" + end do + !$omp end do + end do + end do + + !$omp do ordered(1) + !DEF: /omp_doordered/Block3/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !$omp ordered + !REF: /omp_doordered/j + do j=1,10 + print *, "hello" + end do + !$omp end ordered + end do + !$omp end do + + !$omp do collapse(1) ordered(2) + !DEF: /omp_doordered/Block4/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !DEF: /omp_doordered/Block4/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do j=1,10 + print *, "hello" + end do + end do + !$omp end do + + !$omp parallel num_threads(4) + !$omp do ordered(1) collapse(1) + !DEF: /omp_doordered/Block5/Block1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do i=1,10 + !$omp ordered + !DEF: /omp_doordered/Block5/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + do j=1,10 + print *, "hello" + end do + !$omp end ordered + end do + !$omp end parallel +end program omp_doordered diff --git a/flang/test/Semantics/omp-do-ordered.f90 b/flang/test/Semantics/omp-do-ordered.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/omp-do-ordered.f90 @@ -0,0 +1,58 @@ +!RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.7.1 Ordered Clause + +program omp_doOrdered + integer:: i,j + !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct. + !$omp do ordered(3) + do i = 1,10 + do j = 1, 10 + print *, "hello" + end do + end do + !$omp end do + + do i = 1,10 + do j = 1, 10 + !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct. + !$omp do ordered(2) + do k = 1, 10 + print *, "hello" + end do + !$omp end do + end do + end do + + !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct. + !$omp do ordered(2) + do i = 1,10 + !$omp ordered + do j = 1, 10 + print *, "hello" + end do + !$omp end ordered + end do + !$omp end do + + !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct. + !$omp do collapse(1) ordered(3) + do i = 1,10 + do j = 1, 10 + print *, "hello" + end do + end do + !$omp end do + + !$omp parallel num_threads(4) + !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct. + !$omp do ordered(2) collapse(1) + do i = 1,10 + !$omp ordered + do j = 1, 10 + print *, "hello" + end do + !$omp end ordered + end do + !$omp end parallel +end program omp_doOrdered