Skip to content

Commit 2526455

Browse files
[Flang][OpenMP] Add semantic checks for Worshare construct (#111358)
Add missing semantic checks for the Workshare construct: OpenMP 5.2: 11.4 Workshare Construct - The construct must not contain any user-defined function calls unless either the function is pure and elemental or the function call is contained inside a parallel construct that is nested inside the workshare construct. (Flang-new used to check only the elemental function, but now it needs to be an impure elemental function) - At most one NoWait clause can appear in the Workshare construct. - Add tests for the same.
1 parent d989c24 commit 2526455

File tree

3 files changed

+36
-6
lines changed

3 files changed

+36
-6
lines changed

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

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,23 @@ class OmpWorkshareBlockChecker {
6868
if (const auto *e{GetExpr(context_, expr)}) {
6969
for (const Symbol &symbol : evaluate::CollectSymbols(*e)) {
7070
const Symbol &root{GetAssociationRoot(symbol)};
71-
if (IsFunction(root) && !IsElementalProcedure(root)) {
72-
context_.Say(expr.source,
73-
"User defined non-ELEMENTAL function "
74-
"'%s' is not allowed in a WORKSHARE construct"_err_en_US,
75-
root.name());
71+
if (IsFunction(root)) {
72+
std::string attrs{""};
73+
if (!IsElementalProcedure(root)) {
74+
attrs = " non-ELEMENTAL";
75+
}
76+
if (root.attrs().test(Attr::IMPURE)) {
77+
if (attrs != "") {
78+
attrs = "," + attrs;
79+
}
80+
attrs = " IMPURE" + attrs;
81+
}
82+
if (attrs != "") {
83+
context_.Say(expr.source,
84+
"User defined%s function '%s' is not allowed in a "
85+
"WORKSHARE construct"_err_en_US,
86+
attrs, root.name());
87+
}
7688
}
7789
}
7890
}

flang/test/Semantics/OpenMP/workshare02.f90

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ module my_mod
99
integer function my_func()
1010
my_func = 10
1111
end function my_func
12+
13+
impure integer function impure_my_func()
14+
impure_my_func = 20
15+
end function impure_my_func
16+
17+
impure elemental integer function impure_ele_my_func()
18+
impure_ele_my_func = 20
19+
end function impure_ele_my_func
1220
end module my_mod
1321

1422
subroutine workshare(aa, bb, cc, dd, ee, ff, n)
@@ -61,6 +69,16 @@ subroutine workshare(aa, bb, cc, dd, ee, ff, n)
6169
j = j - my_func()
6270
!$omp end atomic
6371

72+
!ERROR: User defined IMPURE, non-ELEMENTAL function 'impure_my_func' is not allowed in a WORKSHARE construct
73+
cc = impure_my_func()
74+
!ERROR: User defined IMPURE function 'impure_ele_my_func' is not allowed in a WORKSHARE construct
75+
aa(1) = impure_ele_my_func()
76+
6477
!$omp end workshare
6578

79+
!$omp workshare
80+
j = j + 1
81+
!ERROR: At most one NOWAIT clause can appear on the END WORKSHARE directive
82+
!$omp end workshare nowait nowait
83+
6684
end subroutine workshare

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1170,7 +1170,7 @@ def OMP_Workshare : Directive<"workshare"> {
11701170
let category = CA_Executable;
11711171
}
11721172
def OMP_EndWorkshare : Directive<"end workshare"> {
1173-
let allowedClauses = [
1173+
let allowedOnceClauses = [
11741174
VersionedClause<OMPC_NoWait>,
11751175
];
11761176
let leafConstructs = OMP_Workshare.leafConstructs;

0 commit comments

Comments
 (0)