[OpenMP][Clang] Parsing support for num_teams lower bound (#180608)
According to OpenMP 5.2 the num_teams clause should support a lower-bound as modifier for its argument. This PR adds Parsing support for the lower bound in num_teams clause.
This commit is contained in:
parent
b8743de6c5
commit
5524ce826d
@ -12622,6 +12622,10 @@ def err_omp_transparent_invalid_value : Error<"invalid value for transparent cla
|
||||
" expected one of: omp_not_impex, omp_import, omp_export, omp_impex">;
|
||||
def err_omp_transparent_invalid_type : Error<
|
||||
"transparent clause cannot be applied to type: %0">;
|
||||
def err_omp_num_teams_multi_expr_not_allowed
|
||||
: Error<"only two expressions allowed in 'num_teams' clause">;
|
||||
def err_omp_num_teams_lower_bound_larger
|
||||
: Error<"lower bound is greater than upper bound in 'num_teams' clause">;
|
||||
} // end of OpenMP category
|
||||
|
||||
let CategoryName = "Related Result Type Issue" in {
|
||||
|
||||
@ -2290,8 +2290,20 @@ void OMPClausePrinter::VisitOMPDeviceClause(OMPDeviceClause *Node) {
|
||||
|
||||
void OMPClausePrinter::VisitOMPNumTeamsClause(OMPNumTeamsClause *Node) {
|
||||
if (!Node->varlist_empty()) {
|
||||
OS << "num_teams";
|
||||
VisitOMPClauseList(Node, '(');
|
||||
OS << "num_teams(";
|
||||
// Handle lower-bound:upper-bound syntax when there are exactly 2
|
||||
// expressions
|
||||
if (Node->varlist_size() == 2) {
|
||||
llvm::interleave(
|
||||
Node->varlist(), OS,
|
||||
[&](const auto *Expr) { Expr->printPretty(OS, nullptr, Policy, 0); },
|
||||
":");
|
||||
} else {
|
||||
// For single expression or other cases, use comma-separated list
|
||||
llvm::interleaveComma(Node->varlist(), OS, [&](const auto *Expr) {
|
||||
Expr->printPretty(OS, nullptr, Policy, 0);
|
||||
});
|
||||
}
|
||||
OS << ")";
|
||||
}
|
||||
}
|
||||
|
||||
@ -5080,6 +5080,62 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
|
||||
Diag(Tok, diag::err_modifier_expected_colon) << "fallback";
|
||||
}
|
||||
}
|
||||
} // Handle num_teams clause with optional lower-bound:upper-bound syntax
|
||||
if (Kind == OMPC_num_teams && !Tok.is(tok::r_paren) &&
|
||||
!Tok.is(tok::annot_pragma_openmp_end)) {
|
||||
ExprResult FirstExpr = ParseAssignmentExpression();
|
||||
if (FirstExpr.isInvalid()) {
|
||||
SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
|
||||
Data.RLoc = Tok.getLocation();
|
||||
if (!T.consumeClose())
|
||||
Data.RLoc = T.getCloseLocation();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Tok.is(tok::colon)) {
|
||||
// Lower-bound:upper-bound syntax
|
||||
ConsumeToken();
|
||||
ExprResult UpperBound = ParseAssignmentExpression();
|
||||
if (UpperBound.isInvalid()) {
|
||||
SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
|
||||
Data.RLoc = Tok.getLocation();
|
||||
if (!T.consumeClose())
|
||||
Data.RLoc = T.getCloseLocation();
|
||||
return true;
|
||||
}
|
||||
Vars.push_back(FirstExpr.get()); // lower-bound
|
||||
Vars.push_back(UpperBound.get()); // upper-bound
|
||||
Data.RLoc = Tok.getLocation();
|
||||
if (!T.consumeClose())
|
||||
Data.RLoc = T.getCloseLocation();
|
||||
return false; // Success
|
||||
}
|
||||
if (Tok.is(tok::comma)) {
|
||||
Vars.push_back(FirstExpr.get());
|
||||
while (Tok.is(tok::comma)) {
|
||||
ConsumeToken();
|
||||
ExprResult NextExpr = ParseAssignmentExpression();
|
||||
if (NextExpr.isUsable()) {
|
||||
Vars.push_back(NextExpr.get());
|
||||
} else {
|
||||
SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
|
||||
StopBeforeMatch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Data.RLoc = Tok.getLocation();
|
||||
bool HadError = T.consumeClose();
|
||||
if (!HadError)
|
||||
Data.RLoc = T.getCloseLocation();
|
||||
return HadError;
|
||||
}
|
||||
|
||||
// Single value - parse closing paren
|
||||
Vars.push_back(FirstExpr.get());
|
||||
Data.RLoc = Tok.getLocation();
|
||||
if (!T.consumeClose())
|
||||
Data.RLoc = T.getCloseLocation();
|
||||
return false; // Success
|
||||
}
|
||||
|
||||
bool IsComma =
|
||||
|
||||
@ -13508,7 +13508,8 @@ StmtResult SemaOpenMP::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
|
||||
return StmtError();
|
||||
|
||||
if (!checkNumExprsInClause<OMPNumTeamsClause>(
|
||||
*this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed) ||
|
||||
*this, Clauses, /*MaxNum=*/2,
|
||||
diag::err_omp_num_teams_multi_expr_not_allowed) ||
|
||||
!checkNumExprsInClause<OMPThreadLimitClause>(
|
||||
*this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed))
|
||||
return StmtError();
|
||||
@ -14287,16 +14288,20 @@ StmtResult SemaOpenMP::ActOnOpenMPTargetTeamsDirective(
|
||||
return StmtError();
|
||||
}
|
||||
|
||||
unsigned ClauseMaxNumExprs = HasBareClause ? 3 : 1;
|
||||
unsigned DiagNo = HasBareClause
|
||||
? diag::err_ompx_more_than_three_expr_not_allowed
|
||||
: diag::err_omp_multi_expr_not_allowed;
|
||||
if (!checkNumExprsInClause<OMPNumTeamsClause>(*this, Clauses,
|
||||
ClauseMaxNumExprs, DiagNo) ||
|
||||
!checkNumExprsInClause<OMPThreadLimitClause>(*this, Clauses,
|
||||
ClauseMaxNumExprs, DiagNo))
|
||||
return StmtError();
|
||||
unsigned ClauseMaxNumExprs = HasBareClause ? 3 : 2;
|
||||
unsigned NumTeamsDiag = HasBareClause
|
||||
? diag::err_ompx_more_than_three_expr_not_allowed
|
||||
: diag::err_omp_num_teams_multi_expr_not_allowed;
|
||||
unsigned ThreadLimitDiag =
|
||||
HasBareClause ? diag::err_ompx_more_than_three_expr_not_allowed
|
||||
: diag::err_omp_multi_expr_not_allowed;
|
||||
|
||||
if (!checkNumExprsInClause<OMPNumTeamsClause>(
|
||||
*this, Clauses, ClauseMaxNumExprs, NumTeamsDiag) ||
|
||||
!checkNumExprsInClause<OMPThreadLimitClause>(
|
||||
*this, Clauses, ClauseMaxNumExprs, ThreadLimitDiag)) {
|
||||
return StmtError();
|
||||
}
|
||||
return OMPTargetTeamsDirective::Create(getASTContext(), StartLoc, EndLoc,
|
||||
Clauses, AStmt);
|
||||
}
|
||||
@ -14308,7 +14313,8 @@ StmtResult SemaOpenMP::ActOnOpenMPTargetTeamsDistributeDirective(
|
||||
return StmtError();
|
||||
|
||||
if (!checkNumExprsInClause<OMPNumTeamsClause>(
|
||||
*this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed) ||
|
||||
*this, Clauses, /*MaxNum=*/2,
|
||||
diag::err_omp_num_teams_multi_expr_not_allowed) ||
|
||||
!checkNumExprsInClause<OMPThreadLimitClause>(
|
||||
*this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed))
|
||||
return StmtError();
|
||||
@ -14340,7 +14346,8 @@ StmtResult SemaOpenMP::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
|
||||
return StmtError();
|
||||
|
||||
if (!checkNumExprsInClause<OMPNumTeamsClause>(
|
||||
*this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed) ||
|
||||
*this, Clauses, /*MaxNum=*/2,
|
||||
diag::err_omp_num_teams_multi_expr_not_allowed) ||
|
||||
!checkNumExprsInClause<OMPThreadLimitClause>(
|
||||
*this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed))
|
||||
return StmtError();
|
||||
@ -14373,7 +14380,8 @@ StmtResult SemaOpenMP::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
|
||||
return StmtError();
|
||||
|
||||
if (!checkNumExprsInClause<OMPNumTeamsClause>(
|
||||
*this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed) ||
|
||||
*this, Clauses, /*MaxNum=*/2,
|
||||
diag::err_omp_num_teams_multi_expr_not_allowed) ||
|
||||
!checkNumExprsInClause<OMPThreadLimitClause>(
|
||||
*this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed))
|
||||
return StmtError();
|
||||
@ -14409,7 +14417,8 @@ StmtResult SemaOpenMP::ActOnOpenMPTargetTeamsDistributeSimdDirective(
|
||||
return StmtError();
|
||||
|
||||
if (!checkNumExprsInClause<OMPNumTeamsClause>(
|
||||
*this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed) ||
|
||||
*this, Clauses, /*MaxNum=*/2,
|
||||
diag::err_omp_num_teams_multi_expr_not_allowed) ||
|
||||
!checkNumExprsInClause<OMPThreadLimitClause>(
|
||||
*this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed))
|
||||
return StmtError();
|
||||
@ -23880,6 +23889,31 @@ OMPClause *SemaOpenMP::ActOnOpenMPNumTeamsClause(ArrayRef<Expr *> VarList,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// OpenMP 5.2: Validate lower-bound ≤ upper-bound constraint
|
||||
if (VarList.size() == 2) {
|
||||
Expr *LowerBound = VarList[0];
|
||||
Expr *UpperBound = VarList[1];
|
||||
|
||||
// Check if both are compile-time constants for validation
|
||||
if (!LowerBound->isValueDependent() && !UpperBound->isValueDependent() &&
|
||||
LowerBound->isIntegerConstantExpr(getASTContext()) &&
|
||||
UpperBound->isIntegerConstantExpr(getASTContext())) {
|
||||
|
||||
// Get the actual constant values
|
||||
llvm::APSInt LowerVal =
|
||||
LowerBound->EvaluateKnownConstInt(getASTContext());
|
||||
llvm::APSInt UpperVal =
|
||||
UpperBound->EvaluateKnownConstInt(getASTContext());
|
||||
|
||||
if (LowerVal > UpperVal) {
|
||||
Diag(LowerBound->getExprLoc(),
|
||||
diag::err_omp_num_teams_lower_bound_larger)
|
||||
<< LowerBound->getSourceRange() << UpperBound->getSourceRange();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
|
||||
OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
|
||||
DKind, OMPC_num_teams, getLangOpts().OpenMP);
|
||||
|
||||
103
clang/test/OpenMP/num_teams_clause_ast.cpp
Normal file
103
clang/test/OpenMP/num_teams_clause_ast.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
|
||||
// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -verify %s -ast-print | FileCheck %s
|
||||
// expected-no-diagnostics
|
||||
|
||||
#ifndef HEADER
|
||||
#define HEADER
|
||||
|
||||
void foo();
|
||||
|
||||
// CHECK-LABEL: void test_lower_upper_bound()
|
||||
void test_lower_upper_bound() {
|
||||
int lower = 2, upper = 8;
|
||||
// CHECK: #pragma omp teams num_teams(2:8)
|
||||
#pragma omp teams num_teams(2:8)
|
||||
{ foo(); }
|
||||
|
||||
// CHECK: #pragma omp teams num_teams(lower:upper)
|
||||
#pragma omp teams num_teams(lower:upper)
|
||||
{ foo(); }
|
||||
|
||||
// CHECK: #pragma omp target teams num_teams(1:10)
|
||||
#pragma omp target teams num_teams(1:10)
|
||||
{ foo(); }
|
||||
|
||||
// CHECK: #pragma omp target teams distribute num_teams(3:6)
|
||||
#pragma omp target teams distribute num_teams(3:6)
|
||||
for (int i = 0; i < 100; ++i) { }
|
||||
}
|
||||
|
||||
// CHECK-LABEL: void test_various_directives()
|
||||
void test_various_directives() {
|
||||
int lb = 4, ub = 12;
|
||||
|
||||
// CHECK: #pragma omp target teams distribute parallel for num_teams(lb:ub)
|
||||
#pragma omp target teams distribute parallel for num_teams(lb:ub)
|
||||
for (int i = 0; i < 100; ++i) { }
|
||||
|
||||
// CHECK: #pragma omp target teams distribute parallel for simd num_teams(2:16)
|
||||
#pragma omp target teams distribute parallel for simd num_teams(2:16)
|
||||
for (int i = 0; i < 100; ++i) { }
|
||||
|
||||
// CHECK: #pragma omp target teams distribute simd num_teams(1:8)
|
||||
#pragma omp target teams distribute simd num_teams(1:8)
|
||||
for (int i = 0; i < 100; ++i) { }
|
||||
}
|
||||
|
||||
// CHECK-LABEL: void test_nested_expressions()
|
||||
void test_nested_expressions() {
|
||||
int arr[10][10];
|
||||
int x = 5, y = 10;
|
||||
|
||||
// CHECK: #pragma omp teams num_teams(arr[0][0]:arr[1][1])
|
||||
#pragma omp teams num_teams(arr[0][0]:arr[1][1])
|
||||
{ foo(); }
|
||||
|
||||
// CHECK: #pragma omp teams num_teams(arr[x][0]:arr[y][1])
|
||||
#pragma omp teams num_teams(arr[x][0]:arr[y][1])
|
||||
{ foo(); }
|
||||
|
||||
// CHECK: #pragma omp teams num_teams((x + 1):(y - 1))
|
||||
#pragma omp teams num_teams((x + 1):(y - 1))
|
||||
{ foo(); }
|
||||
|
||||
}
|
||||
|
||||
// CHECK-LABEL: void test_multi_level_matching_delimiters()
|
||||
void test_multi_level_matching_delimiters() {
|
||||
int arr[10][10];
|
||||
int x = 5, y = 10;
|
||||
|
||||
// CHECK: #pragma omp teams num_teams(((x + 1) * 2):((y - 1) * 3))
|
||||
#pragma omp teams num_teams(((x + 1) * 2):((y - 1) * 3))
|
||||
{ foo(); }
|
||||
|
||||
|
||||
// CHECK: #pragma omp teams num_teams(arr[arr[0][0]][0]:arr[arr[1][1]][1])
|
||||
#pragma omp teams num_teams(arr[arr[0][0]][0]:arr[arr[1][1]][1])
|
||||
{ foo(); }
|
||||
|
||||
// CHECK: #pragma omp teams num_teams((arr[x][y] + 1):(arr[y][x] - 1))
|
||||
#pragma omp teams num_teams((arr[x][y] + 1):(arr[y][x] - 1))
|
||||
{ foo(); }
|
||||
|
||||
// CHECK: #pragma omp teams num_teams((x + (y * 2)):((x * 2) + y))
|
||||
#pragma omp teams num_teams((x + (y * 2)):((x * 2) + y))
|
||||
{ foo(); }
|
||||
|
||||
// CHECK: #pragma omp teams num_teams((arr[0][1] + arr[2][3]):(arr[4][5] + arr[6][7]))
|
||||
#pragma omp teams num_teams((arr[0][1] + arr[2][3]):(arr[4][5] + arr[6][7]))
|
||||
{ foo(); }
|
||||
}
|
||||
|
||||
// Template tests
|
||||
// CHECK-LABEL: template <typename T> void test_template_type(T lower, T upper)
|
||||
template<typename T>
|
||||
void test_template_type(T lower, T upper) {
|
||||
// CHECK: #pragma omp teams num_teams(lower:upper)
|
||||
#pragma omp teams num_teams(lower:upper)
|
||||
{}
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -95,7 +95,7 @@ T tmain(T argc, T *argv) {
|
||||
// CHECK-NEXT: foo()
|
||||
// CHECK-NEXT: #pragma omp target teams allocate(my_allocator: f) reduction(^: e,f) reduction(&&: g) uses_allocators(my_allocator(traits))
|
||||
// CHECK-NEXT: foo()
|
||||
// CHECK-NEXT: #pragma omp target teams ompx_bare num_teams(1,1,1) thread_limit(d * 1,d * 1,d * 1)
|
||||
// CHECK-NEXT: #pragma omp target teams ompx_bare num_teams(1, 1, 1) thread_limit(d * 1,d * 1,d * 1)
|
||||
// CHECK-NEXT: foo();
|
||||
|
||||
enum Enum { };
|
||||
@ -116,7 +116,7 @@ int main (int argc, char **argv) {
|
||||
a=3;
|
||||
// CHECK-NEXT: a = 3;
|
||||
#pragma omp target teams ompx_bare num_teams(1, 2, 3) thread_limit(2, 4, 6)
|
||||
// CHECK-NEXT: #pragma omp target teams ompx_bare num_teams(1,2,3) thread_limit(2,4,6)
|
||||
// CHECK-NEXT: #pragma omp target teams ompx_bare num_teams(1, 2, 3) thread_limit(2,4,6)
|
||||
a=4;
|
||||
// CHECK-NEXT: a = 4;
|
||||
#pragma omp target teams default(none), private(argc,b) num_teams(f) firstprivate(argv) reduction(| : c, d) reduction(* : e) thread_limit(f+g)
|
||||
|
||||
@ -44,7 +44,7 @@ T tmain(T argc) {
|
||||
#pragma omp target teams distribute num_teams(3.14) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'double'}}
|
||||
for (int i=0; i<100; i++) foo();
|
||||
|
||||
#pragma omp target teams distribute num_teams(1, 2, 3) // expected-error {{only one expression allowed in 'num_teams' clause}}
|
||||
#pragma omp target teams distribute num_teams(1, 2, 3) // expected-error {{only two expressions allowed in 'num_teams' clause}}
|
||||
for (int i=0; i<100; i++) foo();
|
||||
|
||||
#pragma omp target teams distribute thread_limit(1, 2, 3) // expected-error {{only one expression allowed in 'thread_limit' clause}}
|
||||
@ -97,7 +97,7 @@ int main(int argc, char **argv) {
|
||||
#pragma omp target teams distribute num_teams (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
|
||||
for (int i=0; i<100; i++) foo();
|
||||
|
||||
#pragma omp target teams distribute num_teams(1, 2, 3) // expected-error {{only one expression allowed in 'num_teams' clause}}
|
||||
#pragma omp target teams distribute num_teams(1, 2, 3) // expected-error {{only two expressions allowed in 'num_teams' clause}}
|
||||
for (int i=0; i<100; i++) foo();
|
||||
|
||||
#pragma omp target teams distribute thread_limit(1, 2, 3) // expected-error {{only one expression allowed in 'thread_limit' clause}}
|
||||
|
||||
@ -43,7 +43,7 @@ T tmain(T argc) {
|
||||
for (int i=0; i<100; i++) foo();
|
||||
#pragma omp target teams distribute parallel for num_teams(3.14) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'double'}}
|
||||
for (int i=0; i<100; i++) foo();
|
||||
#pragma omp target teams distribute parallel for num_teams(1, 2, 3) // expected-error {{only one expression allowed in 'num_teams' clause}}
|
||||
#pragma omp target teams distribute parallel for num_teams(1, 2, 3) // expected-error {{only two expressions allowed in 'num_teams' clause}}
|
||||
for (int i=0; i<100; i++) foo();
|
||||
#pragma omp target teams distribute parallel for thread_limit(1, 2, 3) // expected-error {{only one expression allowed in 'thread_limit' clause}}
|
||||
for (int i=0; i<100; i++) foo();
|
||||
@ -89,7 +89,7 @@ int main(int argc, char **argv) {
|
||||
#pragma omp target teams distribute parallel for num_teams (3.14) // expected-error {{expression must have integral or unscoped enumeration type, not 'double'}}
|
||||
for (int i=0; i<100; i++) foo();
|
||||
|
||||
#pragma omp target teams distribute parallel for num_teams(1, 2, 3) // expected-error {{only one expression allowed in 'num_teams' clause}}
|
||||
#pragma omp target teams distribute parallel for num_teams(1, 2, 3) // expected-error {{only two expressions allowed in 'num_teams' clause}}
|
||||
for (int i=0; i<100; i++) foo();
|
||||
|
||||
#pragma omp target teams distribute parallel for thread_limit(1, 2, 3) // expected-error {{only one expression allowed in 'thread_limit' clause}}
|
||||
|
||||
@ -58,7 +58,7 @@ T tmain(T argc) {
|
||||
#pragma omp teams num_teams(3.14) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'double'}}
|
||||
foo();
|
||||
#pragma omp target
|
||||
#pragma omp teams num_teams (1, 2, 3) // expected-error {{only one expression allowed in 'num_teams' clause}}
|
||||
#pragma omp teams num_teams (1, 2, 3) // expected-error {{only two expressions allowed in 'num_teams' clause}}
|
||||
foo();
|
||||
#pragma omp target
|
||||
#pragma omp teams thread_limit(1, 2, 3) // expected-error {{only one expression allowed in 'thread_limit' clause}}
|
||||
@ -118,7 +118,7 @@ int main(int argc, char **argv) {
|
||||
foo();
|
||||
|
||||
#pragma omp target
|
||||
#pragma omp teams num_teams (1, 2, 3) // expected-error {{only one expression allowed in 'num_teams' clause}}
|
||||
#pragma omp teams num_teams (1, 2, 3) // expected-error {{only two expressions allowed in 'num_teams' clause}}
|
||||
foo();
|
||||
|
||||
#pragma omp target
|
||||
@ -127,3 +127,123 @@ int main(int argc, char **argv) {
|
||||
|
||||
return tmain<int, 10>(argc); // expected-note {{in instantiation of function template specialization 'tmain<int, 10>' requested here}}
|
||||
}
|
||||
|
||||
// Test invalid syntax cases for num_teams lower-bound:upper-bound
|
||||
void test_invalid_syntax() {
|
||||
int a = 1, b = 2, c = 3;
|
||||
|
||||
// expected-error@+1 {{only two expressions allowed in 'num_teams' clause}}
|
||||
#pragma omp teams num_teams(a, b, c)
|
||||
{ }
|
||||
// expected-error@+1 {{lower bound is greater than upper bound in 'num_teams' clause}}
|
||||
#pragma omp teams num_teams(10:5)
|
||||
{ }
|
||||
|
||||
// expected-error@+1 {{only two expressions allowed in 'num_teams' clause}}
|
||||
#pragma omp target teams num_teams(a, b, c)
|
||||
{ }
|
||||
// expected-error@+1 {{lower bound is greater than upper bound in 'num_teams' clause}}
|
||||
#pragma omp target teams num_teams(8:3)
|
||||
{ }
|
||||
|
||||
// expected-error@+1 {{only two expressions allowed in 'num_teams' clause}}
|
||||
#pragma omp target teams distribute num_teams(a, b, c)
|
||||
for (int i = 0; i < 100; ++i) { }
|
||||
// expected-error@+1 {{lower bound is greater than upper bound in 'num_teams' clause}}
|
||||
#pragma omp target teams distribute num_teams(15:7)
|
||||
for (int i = 0; i < 100; ++i) { }
|
||||
|
||||
// expected-error@+1 {{only two expressions allowed in 'num_teams' clause}}
|
||||
#pragma omp target teams distribute parallel for num_teams(a, b, c)
|
||||
for (int i = 0; i < 100; ++i) { }
|
||||
// expected-error@+1 {{lower bound is greater than upper bound in 'num_teams' clause}}
|
||||
#pragma omp target teams distribute parallel for num_teams(12:4)
|
||||
for (int i = 0; i < 100; ++i) { }
|
||||
|
||||
// Test target teams distribute parallel for simd directive
|
||||
// expected-error@+1 {{only two expressions allowed in 'num_teams' clause}}
|
||||
#pragma omp target teams distribute parallel for simd num_teams(a, b, c)
|
||||
for (int i = 0; i < 100; ++i) { }
|
||||
// expected-error@+1 {{lower bound is greater than upper bound in 'num_teams' clause}}
|
||||
#pragma omp target teams distribute parallel for simd num_teams(20:6)
|
||||
for (int i = 0; i < 100; ++i) { }
|
||||
|
||||
// expected-error@+1 {{only two expressions allowed in 'num_teams' clause}}
|
||||
#pragma omp target teams distribute simd num_teams(a, b, c)
|
||||
for (int i = 0; i < 100; ++i) { }
|
||||
// expected-error@+1 {{lower bound is greater than upper bound in 'num_teams' clause}}
|
||||
#pragma omp target teams distribute simd num_teams(9:2)
|
||||
for (int i = 0; i < 100; ++i) { }
|
||||
}
|
||||
|
||||
// Test non-matching parentheses and brackets
|
||||
void test_non_matching_delimiters() {
|
||||
int arr[10];
|
||||
int x = 5;
|
||||
|
||||
// expected-error@+4 {{expected ')'}}
|
||||
// expected-error@+3 {{expected ')'}}
|
||||
// expected-note@+2 {{to match this '('}}
|
||||
// expected-note@+1 {{to match this '('}}
|
||||
#pragma omp teams num_teams((x + 1:10)
|
||||
{ }
|
||||
|
||||
// expected-error@+2 {{expected ']'}}
|
||||
// expected-note@+1 {{to match this '['}}
|
||||
#pragma omp teams num_teams(arr[0:10)
|
||||
{ }
|
||||
|
||||
// expected-error@+2 {{expected ')'}}
|
||||
// expected-note@+1 {{to match this '('}}
|
||||
#pragma omp teams num_teams(x:((10 + 1))
|
||||
{ }
|
||||
}
|
||||
|
||||
// Test multi-level non-matching parentheses and brackets
|
||||
void test_multi_level_non_matching_delimiters() {
|
||||
int arr[10][10];
|
||||
int x = 5, y = 10;
|
||||
|
||||
// expected-error@+4 {{expected ')'}}
|
||||
// expected-note@+3 {{to match this '('}}
|
||||
// expected-error@+2 {{expected ')'}}
|
||||
// expected-note@+1 {{to match this '('}}
|
||||
#pragma omp teams num_teams(((x + 1) * 2:10)
|
||||
{ }
|
||||
|
||||
// expected-error@+4 {{expected ')'}}
|
||||
// expected-note@+3 {{to match this '('}}
|
||||
// expected-error@+2 {{expected ')'}}
|
||||
// expected-note@+1 {{to match this '('}}
|
||||
#pragma omp teams num_teams((x + (y - 1):10)
|
||||
{ }
|
||||
|
||||
// expected-error@+2 {{expected ']'}}
|
||||
// expected-note@+1 {{to match this '['}}
|
||||
#pragma omp teams num_teams((arr[0 + 1):10)
|
||||
{ }
|
||||
|
||||
// expected-error@+2 {{expected ')'}}
|
||||
// expected-note@+1 {{to match this '('}}
|
||||
#pragma omp teams num_teams(x:((y + 1) * 2)
|
||||
{ }
|
||||
|
||||
// expected-error@+4 {{expected ']'}}
|
||||
// expected-note@+3 {{to match this '['}}
|
||||
// expected-error@+2 {{expected ']'}}
|
||||
// expected-note@+1 {{to match this '['}}
|
||||
#pragma omp teams num_teams(arr[0][1:arr[2][3)
|
||||
{ }
|
||||
}
|
||||
|
||||
template<int Lower, int Upper>
|
||||
void test_template_type_constants() {
|
||||
// expected-error@+1 {{lower bound is greater than upper bound in 'num_teams' clause}}
|
||||
#pragma omp teams num_teams(Lower:Upper)
|
||||
{}
|
||||
}
|
||||
|
||||
void instantiate_template_invalid() {
|
||||
test_template_type_constants<10, 5>(); // expected-note {{in instantiation of function template specialization 'test_template_type_constants<10, 5>' requested here}}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user