Skip to content

Commit 2e26459

Browse files
committed
[Flang][OpenMP] Add semantic checks for OpenMP Depend clause.
Add the semantic checks for the OpenMP 4.5 - 2.13.9 Depend clause. 1. List items in depend clause should not be zero length array sections. 2. A variable that is part of another variable like structure component should not be specified on a depend clause. Test cases : omp-depend01.f90, omp-depend02.f90, omp-depend03.f90 Reviewed By: kiranchandramohan Differential Revision: https://reviews.llvm.org/D89934
1 parent 124c93c commit 2e26459

File tree

5 files changed

+172
-2
lines changed

5 files changed

+172
-2
lines changed

flang/lib/Semantics/check-omp-structure.cpp

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,6 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Ordered &x) {
424424
// Following clauses have a seperate node in parse-tree.h.
425425
CHECK_SIMPLE_PARSER_CLAUSE(OmpAllocateClause, OMPC_allocate)
426426
CHECK_SIMPLE_PARSER_CLAUSE(OmpDefaultClause, OMPC_default)
427-
CHECK_SIMPLE_PARSER_CLAUSE(OmpDependClause, OMPC_depend)
428427
CHECK_SIMPLE_PARSER_CLAUSE(OmpDistScheduleClause, OMPC_dist_schedule)
429428
CHECK_SIMPLE_PARSER_CLAUSE(OmpNowait, OMPC_nowait)
430429
CHECK_SIMPLE_PARSER_CLAUSE(OmpProcBindClause, OMPC_proc_bind)
@@ -597,6 +596,23 @@ void OmpStructureChecker::Enter(const parser::OmpScheduleClause &x) {
597596
}
598597
}
599598

599+
void OmpStructureChecker::Enter(const parser::OmpDependClause &x) {
600+
CheckAllowed(llvm::omp::Clause::OMPC_depend);
601+
if (const auto *inOut{std::get_if<parser::OmpDependClause::InOut>(&x.u)}) {
602+
const auto &designators{std::get<std::list<parser::Designator>>(inOut->t)};
603+
for (const auto &ele : designators) {
604+
if (const auto *dataRef{std::get_if<parser::DataRef>(&ele.u)}) {
605+
CheckDependList(*dataRef);
606+
if (const auto *arr{
607+
std::get_if<common::Indirection<parser::ArrayElement>>(
608+
&dataRef->u)}) {
609+
CheckDependArraySection(*arr, GetLastName(*dataRef));
610+
}
611+
}
612+
}
613+
}
614+
}
615+
600616
llvm::StringRef OmpStructureChecker::getClauseName(llvm::omp::Clause clause) {
601617
return llvm::omp::getOpenMPClauseName(clause);
602618
}
@@ -606,4 +622,54 @@ llvm::StringRef OmpStructureChecker::getDirectiveName(
606622
return llvm::omp::getOpenMPDirectiveName(directive);
607623
}
608624

625+
void OmpStructureChecker::CheckDependList(const parser::DataRef &d) {
626+
std::visit(
627+
common::visitors{
628+
[&](const common::Indirection<parser::ArrayElement> &elem) {
629+
// Check if the base element is valid on Depend Clause
630+
CheckDependList(elem.value().base);
631+
},
632+
[&](const common::Indirection<parser::StructureComponent> &) {
633+
context_.Say(GetContext().clauseSource,
634+
"A variable that is part of another variable "
635+
"(such as an element of a structure) but is not an array "
636+
"element or an array section cannot appear in a DEPEND "
637+
"clause"_err_en_US);
638+
},
639+
[&](const common::Indirection<parser::CoindexedNamedObject> &) {
640+
context_.Say(GetContext().clauseSource,
641+
"Coarrays are not supported in DEPEND clause"_err_en_US);
642+
},
643+
[&](const parser::Name &) { return; },
644+
},
645+
d.u);
646+
}
647+
648+
void OmpStructureChecker::CheckDependArraySection(
649+
const common::Indirection<parser::ArrayElement> &arr,
650+
const parser::Name &name) {
651+
for (const auto &subscript : arr.value().subscripts) {
652+
if (const auto *triplet{
653+
std::get_if<parser::SubscriptTriplet>(&subscript.u)}) {
654+
if (std::get<2>(triplet->t)) {
655+
context_.Say(GetContext().clauseSource,
656+
"Stride should not be specified for array section in DEPEND "
657+
"clause"_err_en_US);
658+
}
659+
const auto &lower{std::get<0>(triplet->t)};
660+
const auto &upper{std::get<1>(triplet->t)};
661+
if (lower && upper) {
662+
const auto lval{GetIntValue(lower)};
663+
const auto uval{GetIntValue(upper)};
664+
if (lval && uval && *uval < *lval) {
665+
context_.Say(GetContext().clauseSource,
666+
"'%s' in DEPEND clause is a zero size array section"_err_en_US,
667+
name.ToString());
668+
break;
669+
}
670+
}
671+
}
672+
}
673+
}
674+
609675
} // namespace Fortran::semantics

flang/lib/Semantics/check-omp-structure.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@ class OmpStructureChecker
165165
void Enter(const parser::OmpScheduleClause &);
166166

167167
private:
168-
169168
bool HasInvalidWorksharingNesting(
170169
const parser::CharBlock &, const OmpDirectiveSet &);
171170

@@ -175,6 +174,10 @@ class OmpStructureChecker
175174

176175
llvm::StringRef getClauseName(llvm::omp::Clause clause) override;
177176
llvm::StringRef getDirectiveName(llvm::omp::Directive directive) override;
177+
178+
void CheckDependList(const parser::DataRef &);
179+
void CheckDependArraySection(
180+
const common::Indirection<parser::ArrayElement> &, const parser::Name &);
178181
};
179182
} // namespace Fortran::semantics
180183
#endif // FORTRAN_SEMANTICS_CHECK_OMP_STRUCTURE_H_

flang/test/Semantics/omp-depend01.f90

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
! RUN: %S/test_errors.sh %s %t %f18 -fopenmp
2+
! OpenMP Version 4.5
3+
! 2.13.9 Depend Clause
4+
! List items used in depend clauses cannot be zero-length array sections.
5+
6+
program omp_depend
7+
integer :: a(10) , b(10,10)
8+
a = 10
9+
b = 20
10+
11+
!$omp parallel
12+
!$omp single
13+
14+
!ERROR: 'a' in DEPEND clause is a zero size array section
15+
!ERROR: 'b' in DEPEND clause is a zero size array section
16+
!$omp task shared(a,b) depend(out: a(2:1), b(3:1, 1:-1))
17+
a(2:1) = b(2, 2)
18+
!$omp end task
19+
20+
!ERROR: Stride should not be specified for array section in DEPEND clause
21+
!$omp task shared(x) depend(in: a(5:10:1))
22+
print *, a(5:10), b
23+
!$omp end task
24+
25+
!$omp end single
26+
!$omp end parallel
27+
28+
end program omp_depend

flang/test/Semantics/omp-depend02.f90

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
! RUN: %S/test_errors.sh %s %t %f18 -fopenmp
2+
! OpenMP Version 4.5
3+
! 2.13.9 Depend Clause
4+
! A variable that is part of another variable
5+
! (such as an element of a structure) but is not an array element or
6+
! an array section cannot appear in a DEPEND clause
7+
8+
subroutine vec_mult(N)
9+
implicit none
10+
integer :: i, N
11+
real, allocatable :: p(:), v1(:), v2(:)
12+
13+
type my_type
14+
integer :: a(10)
15+
end type my_type
16+
17+
type(my_type) :: my_var
18+
allocate( p(N), v1(N), v2(N) )
19+
20+
!$omp parallel num_threads(2)
21+
!$omp single
22+
23+
!$omp task depend(out:v1)
24+
call init(v1, N)
25+
!$omp end task
26+
27+
!$omp task depend(out:v2)
28+
call init(v2, N)
29+
!$omp end task
30+
31+
!ERROR: A variable that is part of another variable (such as an element of a structure) but is not an array element or an array section cannot appear in a DEPEND clause
32+
!$omp target nowait depend(in:v1,v2, my_var%a) depend(out:p) &
33+
!$omp& map(to:v1,v2) map(from: p)
34+
!$omp parallel do
35+
do i=1,N
36+
p(i) = v1(i) * v2(i)
37+
end do
38+
!$omp end target
39+
40+
!$omp task depend(in:p)
41+
call output(p, N)
42+
!$omp end task
43+
44+
!$omp end single
45+
!$omp end parallel
46+
47+
deallocate( p, v1, v2 )
48+
49+
end subroutine

flang/test/Semantics/omp-depend03.f90

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
! RUN: %S/test_errors.sh %s %t %f18 -fopenmp
2+
! OpenMP Version 4.5
3+
! 2.13.9 Depend Clause
4+
! Coarrays are not supported in depend clause
5+
6+
program omp_depend_coarray
7+
integer :: a(3)[*], b(3) , k
8+
9+
a(:) = this_image()
10+
b(:) = a(:)[1]
11+
k = 10
12+
13+
!$omp parallel
14+
!$omp single
15+
!ERROR: Coarrays are not supported in DEPEND clause
16+
!$omp task shared(b) depend(out: a(:)[1])
17+
b = a + k
18+
!$omp end task
19+
!$omp end single
20+
!$omp end parallel
21+
22+
print *, a, b
23+
24+
end program omp_depend_coarray

0 commit comments

Comments
 (0)