Skip to content

Commit 59ff7bb

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 59ff7bb

File tree

4 files changed

+114
-2
lines changed

4 files changed

+114
-2
lines changed

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

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

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

Lines changed: 5 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

@@ -230,6 +233,8 @@ class OmpStructureChecker
230233
const parser::OmpObjectList &ompObjectList);
231234
void CheckPredefinedAllocatorRestriction(
232235
const parser::CharBlock &source, const parser::Name &name);
236+
void CheckSymbolsForOrderClause(
237+
const parser::Name &name, bool checkRuntimeAPICall);
233238
bool isPredefinedAllocator{false};
234239

235240
void CheckAllowedRequiresClause(llvmOmpClause clause);
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)