Skip to content

Commit 5791620

Browse files
[LLVM-Flang][OpenMP] Add semantic checks for order clause
Fix: - Move the order clause to allowedOnceClauses list in the `OMP_DistributeParallelDoSimd` and `OMP_TargetParallelDoSimd` definitions OpenMP 5.2: 10.3 Order clause restrictions - A region that corresponds to a construct with an order clause that specifies concurrent may not contain calls to procedures that contain OpenMP directives. - A region that corresponds to a construct with an order clause that specifies concurrent may not contain OpenMP runtime API calls. OpenMP 5.1: 2.11.3 order Clause restriction: - At most one order clause may appear on a construct.
1 parent 1469d82 commit 5791620

File tree

4 files changed

+113
-2
lines changed

4 files changed

+113
-2
lines changed

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,46 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
598598
CheckDistLinear(x);
599599
}
600600
}
601+
602+
// OpenMP 5.2: 10.3 Order clause restrictions
603+
void OmpStructureChecker::Enter(const parser::ProcedureDesignator &x) {
604+
if (!dirContext_.empty() &&
605+
(llvm::omp::allDoSet | llvm::omp::allSimdSet |
606+
llvm::omp::allDistributeSet)
607+
.test(GetContext().directive)) {
608+
if (FindClause(llvm::omp::Clause::OMPC_order)) {
609+
const auto &name{std::get<parser::Name>(x.u)};
610+
if (std::get<parser::OmpOrderClause::Type>(orderClause.v.t) ==
611+
parser::OmpOrderClause::Type::Concurrent &&
612+
llvm::StringRef(name.ToString()).starts_with_insensitive("omp_")) {
613+
context_.Say(name.source,
614+
"The OpenMP runtime API calls are not allowed in "
615+
"the `order(concurrent)` clause region"_err_en_US);
616+
}
617+
}
618+
}
619+
}
620+
621+
// OpenMP 5.2: 10.3 Order clause restrictions
622+
void OmpStructureChecker::Enter(const parser::Designator &x) {
623+
if (!dirContext_.empty() &&
624+
(llvm::omp::allDoSet | llvm::omp::allSimdSet |
625+
llvm::omp::allDistributeSet)
626+
.test(GetContext().directive)) {
627+
if (const auto *clause{FindClause(llvm::omp::Clause::OMPC_order)}) {
628+
const auto &orderClause{std::get<parser::OmpClause::Order>(clause->u)};
629+
const auto &name{parser::Unwrap<parser::Name>(x.u)};
630+
if (std::get<parser::OmpOrderClause::Type>(orderClause.v.t) ==
631+
parser::OmpOrderClause::Type::Concurrent &&
632+
name->symbol->test(Symbol::Flag::OmpThreadprivate)) {
633+
context_.Say(name->source,
634+
"A THREADPRIVATE variable cannot appear in an `order(concurrent)` "
635+
"clause region, the behavior is unspecified"_err_en_US);
636+
}
637+
}
638+
}
639+
}
640+
601641
const parser::Name OmpStructureChecker::GetLoopIndex(
602642
const parser::DoConstruct *x) {
603643
using Bounds = parser::LoopControl::Bounds;

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ class OmpStructureChecker
131131
void Enter(const parser::OmpAtomicCapture &);
132132
void Leave(const parser::OmpAtomic &);
133133

134+
void Enter(const parser::ProcedureDesignator &);
135+
void Enter(const parser::Designator &);
136+
134137
#define GEN_FLANG_CLAUSE_CHECK_ENTER
135138
#include "llvm/Frontend/OpenMP/OMP.inc"
136139

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
! REQUIRES: openmp_runtime
2+
! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=50
3+
! OpenMP Version 5.2
4+
! Various checks for the order clause
5+
! 10.3 `order` Clause
6+
7+
! Case 1
8+
subroutine omp_order_runtime_api_call_01()
9+
use omp_lib
10+
integer :: i
11+
!$omp do order(concurrent)
12+
do i = 1, 5
13+
!ERROR: The OpenMP runtime API calls are not allowed in the `order(concurrent)` clause region
14+
print*, omp_get_thread_num()
15+
end do
16+
!$omp end do
17+
end subroutine omp_order_runtime_api_call_01
18+
19+
subroutine omp_order_runtime_api_call_02()
20+
use omp_lib
21+
integer :: i, num_threads
22+
!$omp do order(concurrent)
23+
do i = 1, 5
24+
!ERROR: The OpenMP runtime API calls are not allowed in the `order(concurrent)` clause region
25+
call omp_set_num_threads(num_threads)
26+
end do
27+
!$omp end do
28+
end subroutine omp_order_runtime_api_call_02
29+
30+
! Case 2
31+
subroutine test_order_threadprivate()
32+
integer :: i, j = 1, x
33+
!$omp threadprivate(j)
34+
!$omp parallel do order(concurrent)
35+
do i = 1, 5
36+
!ERROR: A THREADPRIVATE variable cannot appear in an `order(concurrent)` clause region, the behavior is unspecified
37+
j = x + 1
38+
end do
39+
!$omp end parallel do
40+
end subroutine
41+
42+
! Case 3
43+
subroutine omp_order_duplicate_01()
44+
implicit none
45+
integer :: i, j
46+
!ERROR: At most one ORDER clause can appear on the TARGET PARALLEL DO SIMD directive
47+
!$OMP target parallel do simd ORDER(concurrent) ORDER(concurrent)
48+
do i = 1, 5
49+
j = j + 1
50+
end do
51+
!$omp end target parallel do simd
52+
end subroutine
53+
54+
subroutine omp_order_duplicate_02()
55+
integer :: i, j
56+
!$omp teams
57+
!ERROR: At most one ORDER clause can appear on the DISTRIBUTE PARALLEL DO SIMD directive
58+
!$omp distribute parallel do simd order(concurrent) order(concurrent)
59+
do i = 1, 5
60+
j = j + 1
61+
end do
62+
!$omp end distribute parallel do simd
63+
!$omp end teams
64+
end subroutine

llvm/include/llvm/Frontend/OpenMP/OMP.td

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,7 +1235,6 @@ def OMP_DistributeParallelDoSimd : Directive<"distribute parallel do simd"> {
12351235
VersionedClause<OMPC_Linear>,
12361236
VersionedClause<OMPC_NonTemporal>,
12371237
VersionedClause<OMPC_NumThreads>,
1238-
VersionedClause<OMPC_Order, 50>,
12391238
VersionedClause<OMPC_Private>,
12401239
VersionedClause<OMPC_ProcBind>,
12411240
VersionedClause<OMPC_Reduction>,
@@ -1244,6 +1243,9 @@ def OMP_DistributeParallelDoSimd : Directive<"distribute parallel do simd"> {
12441243
VersionedClause<OMPC_Shared>,
12451244
VersionedClause<OMPC_SimdLen>,
12461245
];
1246+
let allowedOnceClauses = [
1247+
VersionedClause<OMPC_Order, 50>,
1248+
];
12471249
let leafConstructs = [OMP_Distribute, OMP_Parallel, OMP_Do, OMP_Simd];
12481250
let category = CA_Executable;
12491251
}
@@ -1908,7 +1910,6 @@ def OMP_TargetParallelDoSimd : Directive<"target parallel do simd"> {
19081910
VersionedClause<OMPC_NonTemporal>,
19091911
VersionedClause<OMPC_NoWait>,
19101912
VersionedClause<OMPC_NumThreads>,
1911-
VersionedClause<OMPC_Order, 50>,
19121913
VersionedClause<OMPC_Ordered>,
19131914
VersionedClause<OMPC_Private>,
19141915
VersionedClause<OMPC_ProcBind>,
@@ -1919,6 +1920,9 @@ def OMP_TargetParallelDoSimd : Directive<"target parallel do simd"> {
19191920
VersionedClause<OMPC_SimdLen>,
19201921
VersionedClause<OMPC_UsesAllocators>,
19211922
];
1923+
let allowedOnceClauses = [
1924+
VersionedClause<OMPC_Order, 50>
1925+
];
19221926
let leafConstructs = [OMP_Target, OMP_Parallel, OMP_Do, OMP_Simd];
19231927
let category = CA_Executable;
19241928
}

0 commit comments

Comments
 (0)