Add Semantic check for Flang OpenMP 4.5 - 2.7.1 ordered and collapse clause

Semantic check added to check and restrict the value of the parameter in the COLLAPSE or ORDERED clause
if it is larger than the number of nested loops following the construct.

Test Cases:
omp-do-collapse-positivecases.f90
omp-do-collapse.f90
omp-do-ordered-positivecases.f90
omp-do-ordered.f90

Reviewed by: Kiran Chandramohan @kiranchandramohan , Valentin Clement @clementval

Differential Revision: https://reviews.llvm.org/D89860
This commit is contained in:
Yashaswini 2020-11-22 18:36:59 +05:30
parent 791040cd8b
commit 29dffb0c8a
5 changed files with 217 additions and 7 deletions

View File

@ -305,6 +305,12 @@ public:
}
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 @@ private:
}
// 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 @@ private:
void CheckDataCopyingClause(
const parser::Name &, const Symbol &, Symbol::Flag);
void CheckAssocLoopLevel(std::int64_t level, const parser::OmpClause *clause);
};
template <typename T>
@ -777,7 +786,7 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPLoopConstruct &x) {
}
ClearDataSharingAttributeObjects();
SetContextAssociatedLoopLevel(GetAssociatedLoopLevelFromClauses(clauseList));
PrivatizeAssociatedLoopIndex(x);
PrivatizeAssociatedLoopIndexAndCheckLoopLevel(x);
return true;
}
@ -824,24 +833,32 @@ std::int64_t OmpAttributeVisitor::GetAssociatedLoopLevelFromClauses(
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<parser::OmpClause::Ordered>(&clause.u)}) {
if (const auto v{EvaluateInt64(context_, orderedClause->v)}) {
orderedLevel = *v;
}
ordClause = &clause;
}
if (const auto *collapseClause{
std::get_if<parser::OmpClause::Collapse>(&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 @@ std::int64_t OmpAttributeVisitor::GetAssociatedLoopLevelFromClauses(
// 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 @@ void OmpAttributeVisitor::PrivatizeAssociatedLoopIndex(
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) {

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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