Skip to content

Commit 29dffb0

Browse files
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
1 parent 791040c commit 29dffb0

File tree

5 files changed

+217
-7
lines changed

5 files changed

+217
-7
lines changed

flang/lib/Semantics/resolve-directives.cpp

+30-7
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,12 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
305305
}
306306
void Post(const parser::Name &);
307307

308+
const parser::OmpClause *associatedClause{nullptr};
309+
void SetAssociatedClause(const parser::OmpClause &c) {
310+
associatedClause = &c;
311+
}
312+
const parser::OmpClause *GetAssociatedClause() { return associatedClause; }
313+
308314
private:
309315
std::int64_t GetAssociatedLoopLevelFromClauses(const parser::OmpClauseList &);
310316

@@ -344,7 +350,8 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
344350
}
345351

346352
// Predetermined DSA rules
347-
void PrivatizeAssociatedLoopIndex(const parser::OpenMPLoopConstruct &);
353+
void PrivatizeAssociatedLoopIndexAndCheckLoopLevel(
354+
const parser::OpenMPLoopConstruct &);
348355
void ResolveSeqLoopIndexInParallelOrTaskConstruct(const parser::Name &);
349356

350357
void ResolveOmpObjectList(const parser::OmpObjectList &, Symbol::Flag);
@@ -362,6 +369,8 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
362369

363370
void CheckDataCopyingClause(
364371
const parser::Name &, const Symbol &, Symbol::Flag);
372+
373+
void CheckAssocLoopLevel(std::int64_t level, const parser::OmpClause *clause);
365374
};
366375

367376
template <typename T>
@@ -777,7 +786,7 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPLoopConstruct &x) {
777786
}
778787
ClearDataSharingAttributeObjects();
779788
SetContextAssociatedLoopLevel(GetAssociatedLoopLevelFromClauses(clauseList));
780-
PrivatizeAssociatedLoopIndex(x);
789+
PrivatizeAssociatedLoopIndexAndCheckLoopLevel(x);
781790
return true;
782791
}
783792

@@ -824,24 +833,32 @@ std::int64_t OmpAttributeVisitor::GetAssociatedLoopLevelFromClauses(
824833
const parser::OmpClauseList &x) {
825834
std::int64_t orderedLevel{0};
826835
std::int64_t collapseLevel{0};
836+
837+
const parser::OmpClause *ordClause{nullptr};
838+
const parser::OmpClause *collClause{nullptr};
839+
827840
for (const auto &clause : x.v) {
828841
if (const auto *orderedClause{
829842
std::get_if<parser::OmpClause::Ordered>(&clause.u)}) {
830843
if (const auto v{EvaluateInt64(context_, orderedClause->v)}) {
831844
orderedLevel = *v;
832845
}
846+
ordClause = &clause;
833847
}
834848
if (const auto *collapseClause{
835849
std::get_if<parser::OmpClause::Collapse>(&clause.u)}) {
836850
if (const auto v{EvaluateInt64(context_, collapseClause->v)}) {
837851
collapseLevel = *v;
838852
}
853+
collClause = &clause;
839854
}
840855
}
841856

842857
if (orderedLevel && (!collapseLevel || orderedLevel >= collapseLevel)) {
858+
SetAssociatedClause(*ordClause);
843859
return orderedLevel;
844860
} else if (!orderedLevel && collapseLevel) {
861+
SetAssociatedClause(*collClause);
845862
return collapseLevel;
846863
} // orderedLevel < collapseLevel is an error handled in structural checks
847864
return 1; // default is outermost loop
@@ -855,10 +872,7 @@ std::int64_t OmpAttributeVisitor::GetAssociatedLoopLevelFromClauses(
855872
// increment of the associated do-loop.
856873
// - The loop iteration variables in the associated do-loops of a simd
857874
// construct with multiple associated do-loops are lastprivate.
858-
//
859-
// TODO: revisit after semantics checks are completed for do-loop association of
860-
// collapse and ordered
861-
void OmpAttributeVisitor::PrivatizeAssociatedLoopIndex(
875+
void OmpAttributeVisitor::PrivatizeAssociatedLoopIndexAndCheckLoopLevel(
862876
const parser::OpenMPLoopConstruct &x) {
863877
std::int64_t level{GetContext().associatedLoopLevel};
864878
if (level <= 0) {
@@ -887,7 +901,16 @@ void OmpAttributeVisitor::PrivatizeAssociatedLoopIndex(
887901
const auto it{block.begin()};
888902
loop = it != block.end() ? GetDoConstructIf(*it) : nullptr;
889903
}
890-
CHECK(level == 0);
904+
CheckAssocLoopLevel(level, GetAssociatedClause());
905+
}
906+
void OmpAttributeVisitor::CheckAssocLoopLevel(
907+
std::int64_t level, const parser::OmpClause *clause) {
908+
if (clause && level != 0) {
909+
context_.Say(clause->source,
910+
"The value of the parameter in the COLLAPSE or ORDERED clause must"
911+
" not be larger than the number of nested loops"
912+
" following the construct."_err_en_US);
913+
}
891914
}
892915

893916
bool OmpAttributeVisitor::Pre(const parser::OpenMPSectionsConstruct &x) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
!RUN: %S/test_errors.sh %s %t %f18 -fopenmp
2+
! OpenMP Version 4.5
3+
! 2.7.1 Collapse Clause Positive cases
4+
5+
!DEF: /omp_docollapse MainProgram
6+
program omp_docollapse
7+
!DEF: /omp_docollapse/i ObjectEntity INTEGER(4)
8+
!DEF: /omp_docollapse/j ObjectEntity INTEGER(4)
9+
!DEF: /omp_docollapse/k ObjectEntity INTEGER(4)
10+
integer i, j, k
11+
!$omp do collapse(2)
12+
!DEF: /omp_docollapse/Block1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
13+
do i=1,10
14+
!DEF: /omp_docollapse/Block1/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
15+
do j=1,10
16+
!REF: /omp_docollapse/k
17+
do k=1,10
18+
print *, "hello"
19+
end do
20+
end do
21+
end do
22+
!$omp end do
23+
24+
!REF: /omp_docollapse/i
25+
do i=1,10
26+
!$omp do collapse(2)
27+
!DEF: /omp_docollapse/Block1/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
28+
do j=1,10
29+
!DEF: /omp_docollapse/Block1/k (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
30+
do k=1,10
31+
print *, "hello"
32+
end do
33+
end do
34+
!$omp end do
35+
end do
36+
end program omp_docollapse
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
!RUN: %S/test_errors.sh %s %t %f18 -fopenmp
2+
! OpenMP Version 4.5
3+
! 2.7.1 Collapse Clause
4+
program omp_doCollapse
5+
integer:: i,j
6+
!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.
7+
!$omp do collapse(3)
8+
do i = 1,10
9+
do j = 1, 10
10+
print *, "hello"
11+
end do
12+
end do
13+
!$omp end do
14+
15+
do i = 1,10
16+
do j = 1, 10
17+
!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.
18+
!$omp do collapse(2)
19+
do k = 1, 10
20+
print *, "hello"
21+
end do
22+
!$omp end do
23+
end do
24+
end do
25+
end program omp_doCollapse
26+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
!RUN: %S/test_errors.sh %s %t %f18 -fopenmp
2+
! OpenMP Version 4.5
3+
! 2.7.1 Ordered Clause positive cases.
4+
5+
!DEF: /omp_doordered MainProgram
6+
program omp_doordered
7+
!DEF: /omp_doordered/i ObjectEntity INTEGER(4)
8+
!DEF: /omp_doordered/j ObjectEntity INTEGER(4)
9+
integer i, j
10+
!$omp do ordered(2)
11+
!DEF: /omp_doordered/Block1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
12+
do i=1,10
13+
!DEF: /omp_doordered/Block1/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
14+
do j=1,10
15+
print *, "hello"
16+
end do
17+
end do
18+
!$omp end do
19+
20+
!REF: /omp_doordered/i
21+
do i=1,10
22+
!REF: /omp_doordered/j
23+
do j=1,10
24+
!$omp do ordered(1)
25+
!DEF: /omp_doordered/Block2/k (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
26+
do k=1,10
27+
print *, "hello"
28+
end do
29+
!$omp end do
30+
end do
31+
end do
32+
33+
!$omp do ordered(1)
34+
!DEF: /omp_doordered/Block3/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
35+
do i=1,10
36+
!$omp ordered
37+
!REF: /omp_doordered/j
38+
do j=1,10
39+
print *, "hello"
40+
end do
41+
!$omp end ordered
42+
end do
43+
!$omp end do
44+
45+
!$omp do collapse(1) ordered(2)
46+
!DEF: /omp_doordered/Block4/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
47+
do i=1,10
48+
!DEF: /omp_doordered/Block4/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
49+
do j=1,10
50+
print *, "hello"
51+
end do
52+
end do
53+
!$omp end do
54+
55+
!$omp parallel num_threads(4)
56+
!$omp do ordered(1) collapse(1)
57+
!DEF: /omp_doordered/Block5/Block1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
58+
do i=1,10
59+
!$omp ordered
60+
!DEF: /omp_doordered/Block5/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
61+
do j=1,10
62+
print *, "hello"
63+
end do
64+
!$omp end ordered
65+
end do
66+
!$omp end parallel
67+
end program omp_doordered
+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
!RUN: %S/test_errors.sh %s %t %f18 -fopenmp
2+
! OpenMP Version 4.5
3+
! 2.7.1 Ordered Clause
4+
5+
program omp_doOrdered
6+
integer:: i,j
7+
!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.
8+
!$omp do ordered(3)
9+
do i = 1,10
10+
do j = 1, 10
11+
print *, "hello"
12+
end do
13+
end do
14+
!$omp end do
15+
16+
do i = 1,10
17+
do j = 1, 10
18+
!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.
19+
!$omp do ordered(2)
20+
do k = 1, 10
21+
print *, "hello"
22+
end do
23+
!$omp end do
24+
end do
25+
end do
26+
27+
!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.
28+
!$omp do ordered(2)
29+
do i = 1,10
30+
!$omp ordered
31+
do j = 1, 10
32+
print *, "hello"
33+
end do
34+
!$omp end ordered
35+
end do
36+
!$omp end do
37+
38+
!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.
39+
!$omp do collapse(1) ordered(3)
40+
do i = 1,10
41+
do j = 1, 10
42+
print *, "hello"
43+
end do
44+
end do
45+
!$omp end do
46+
47+
!$omp parallel num_threads(4)
48+
!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.
49+
!$omp do ordered(2) collapse(1)
50+
do i = 1,10
51+
!$omp ordered
52+
do j = 1, 10
53+
print *, "hello"
54+
end do
55+
!$omp end ordered
56+
end do
57+
!$omp end parallel
58+
end program omp_doOrdered

0 commit comments

Comments
 (0)