Skip to content

[clang][OpenMP] OpenMP 6.0 updates to restrictions with order/concurrent #125621

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions clang/include/clang/Basic/OpenMPKinds.h
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,14 @@ bool isOpenMPInformationalDirective(OpenMPDirectiveKind DKind);
/// \return true - if the above condition is met for this directive
/// otherwise - false.
bool isOpenMPCapturingDirective(OpenMPDirectiveKind DKind);

/// Checks if the specified directive is an order concurrent nestable
/// directive that can be nested within region corresponding to construct
/// on which order clause was specified with concurrent as ordering argument.
/// \param DKind Specified directive.
/// \return true - if the above condition is met for this directive
/// otherwise - false.
bool isOpenMPOrderConcurrentNestableDirective(OpenMPDirectiveKind DKind);
}

template <>
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/Basic/OpenMPKinds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,12 @@ bool clang::isOpenMPCapturingDirective(OpenMPDirectiveKind DKind) {
return false;
}

bool clang::isOpenMPOrderConcurrentNestableDirective(
OpenMPDirectiveKind DKind) {
return DKind == OMPD_atomic || DKind == OMPD_loop || DKind == OMPD_simd ||
DKind == OMPD_parallel || isOpenMPLoopTransformationDirective(DKind);
}

void clang::getOpenMPCaptureRegions(
SmallVectorImpl<OpenMPDirectiveKind> &CaptureRegions,
OpenMPDirectiveKind DKind) {
Expand Down
30 changes: 22 additions & 8 deletions clang/lib/Sema/SemaOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4788,13 +4788,26 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
getLeafOrCompositeConstructs(ParentRegion, LeafOrComposite);
OpenMPDirectiveKind EnclosingConstruct = ParentLOC.back();

if (SemaRef.LangOpts.OpenMP >= 51 && Stack->isParentOrderConcurrent() &&
CurrentRegion != OMPD_simd && CurrentRegion != OMPD_loop &&
CurrentRegion != OMPD_parallel &&
!isOpenMPCombinedParallelADirective(CurrentRegion)) {
SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_order)
<< getOpenMPDirectiveName(CurrentRegion);
return true;
if (Stack->isParentOrderConcurrent()) {
bool InvalidOrderNesting = false;
if ((SemaRef.LangOpts.OpenMP == 51 || SemaRef.LangOpts.OpenMP == 52) &&
CurrentRegion != OMPD_simd && CurrentRegion != OMPD_loop &&
CurrentRegion != OMPD_parallel &&
!isOpenMPCombinedParallelADirective(CurrentRegion)) {
InvalidOrderNesting = true;
} else if (SemaRef.LangOpts.OpenMP >= 60 &&
!isOpenMPOrderConcurrentNestableDirective(CurrentRegion)) {
// OpenMP 6.0 [12.3 order Clause, Restrictions]
// Only regions that correspond to order-concurrent-nestable constructs
// or order-concurrent-nestable routines may be strictly nested regions
// of regions that correspond to constructs on which the order clause is
// specified with concurrent as the ordering argument.
InvalidOrderNesting = true;
}
if (InvalidOrderNesting) {
SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_order)
<< getOpenMPDirectiveName(CurrentRegion);
}
}
if (isOpenMPSimdDirective(ParentRegion) &&
((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
Expand Down Expand Up @@ -7114,7 +7127,8 @@ ExprResult SemaOpenMP::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
if (!CalleeFnDecl)
return Call;

if (getLangOpts().OpenMP >= 51 && CalleeFnDecl->getIdentifier() &&
if (getLangOpts().OpenMP >= 51 && getLangOpts().OpenMP < 60 &&
CalleeFnDecl->getIdentifier() &&
CalleeFnDecl->getName().starts_with_insensitive("omp_")) {
// checking for any calls inside an Order region
if (Scope && Scope->isOpenMPOrderClauseScope())
Expand Down
60 changes: 56 additions & 4 deletions clang/test/OpenMP/for_order_messages.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -triple x86_64-unknown-unknown -verify=expected,omp50 %s -Wuninitialized
// RUN: %clang_cc1 -fsyntax-only -fopenmp -triple x86_64-unknown-unknown -verify=expected,omp51 %s -Wuninitialized
// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=51 -triple x86_64-unknown-unknown -verify=expected,omp51 %s -Wuninitialized
// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=52 -triple x86_64-unknown-unknown -verify=expected,omp51 %s -Wuninitialized
// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=60 -triple x86_64-unknown-unknown -verify=expected,omp60 %s -Wuninitialized

// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=50 -triple x86_64-unknown-unknown -verify=expected,omp50 %s -Wuninitialized
// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -triple x86_64-unknown-unknown -verify=expected,omp51 %s -Wuninitialized
// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=51 -triple x86_64-unknown-unknown -verify=expected,omp51 %s -Wuninitialized
// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=52 -triple x86_64-unknown-unknown -verify=expected,omp51 %s -Wuninitialized
// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=60 -triple x86_64-unknown-unknown -verify=expected,omp60 %s -Wuninitialized

extern int omp_get_num_threads (void);

Expand Down Expand Up @@ -35,13 +39,61 @@ int main(int argc, char **argv) {

#pragma omp parallel for order(reproducible: concurrent) // omp50-error {{expected 'concurrent' in OpenMP clause 'order'}}
for (int i = 0; i < 10; ++i) {
#pragma omp target //omp51-error {{construct 'target' not allowed in a region associated with a directive with 'order' clause}}
#pragma omp target //omp51-error {{construct 'target' not allowed in a region associated with a directive with 'order' clause}} omp60-error {{construct 'target' not allowed in a region associated with a directive with 'order' clause}}
A++;
}

#pragma omp parallel for order(unconstrained: concurrent) // omp50-error {{expected 'concurrent' in OpenMP clause 'order'}}
for (int i = 0; i < 10; ++i) {
#pragma omp target //omp51-error {{construct 'target' not allowed in a region associated with a directive with 'order' clause}}
#pragma omp target //omp51-error {{construct 'target' not allowed in a region associated with a directive with 'order' clause}} omp60-error {{construct 'target' not allowed in a region associated with a directive with 'order' clause}}
A++;
}

#pragma omp loop bind(parallel) order(concurrent)
for (int i = 0; i < 10; ++i) {
#pragma omp parallel for //omp60-error {{construct 'parallel for' not allowed in a region associated with a directive with 'order' clause}}
for (int j = 0; j < 10; ++j) {
A += j;
}
}

#pragma omp distribute order(concurrent)
for (int i = 0; i < 10; ++i) {
#pragma omp parallel for simd //omp60-error {{construct 'parallel for simd' not allowed in a region associated with a directive with 'order' clause}}
for (int j = 0; j < 10; ++j) {
A += j;
}
}

#pragma omp for order(concurrent)
for (int i = 0; i < 10; ++i) {
#pragma omp parallel master //omp60-error {{construct 'parallel master' not allowed in a region associated with a directive with 'order' clause}}
for (int j = 0; j < 10; ++j) {
A += j;
}
}

#pragma omp for order(concurrent)
for (int i = 0; i < 10; ++i) {
#pragma omp parallel master taskloop //omp60-error {{construct 'parallel master taskloop' not allowed in a region associated with a directive with 'order' clause}}
for (int j = 0; j < 10; ++j) {
A += j;
}
}

#pragma omp for order(concurrent)
for (int i = 0; i < 10; ++i) {
#pragma omp parallel master taskloop simd //omp60-error {{construct 'parallel master taskloop simd' not allowed in a region associated with a directive with 'order' clause}}
for (int j = 0; j < 10; ++j) {
A += j;
}
}

#pragma omp for order(concurrent)
for (int i = 0; i < 10; ++i) {
#pragma omp parallel sections //omp60-error {{construct 'parallel sections' not allowed in a region associated with a directive with 'order' clause}}
{
A++;
}
}
}