diff --git a/clang/docs/OpenMPSupport.rst b/clang/docs/OpenMPSupport.rst --- a/clang/docs/OpenMPSupport.rst +++ b/clang/docs/OpenMPSupport.rst @@ -147,7 +147,7 @@ +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | task extension | task affinity | :part:`not upstream` | https://github.com/jklinkenberg/openmp/tree/task-affinity | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ -| task extension | clause: depend on the taskwait construct | :part:`worked on` | | +| task extension | clause: depend on the taskwait construct | :part:`mostly done` | D113540 (regular codegen only) | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | task extension | depend objects and detachable tasks | :good:`done` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ diff --git a/clang/include/clang/AST/StmtOpenMP.h b/clang/include/clang/AST/StmtOpenMP.h --- a/clang/include/clang/AST/StmtOpenMP.h +++ b/clang/include/clang/AST/StmtOpenMP.h @@ -2569,15 +2569,20 @@ /// \param C AST context. /// \param StartLoc Starting location of the directive kind. /// \param EndLoc Ending Location of the directive. + /// \param Clauses List of clauses. /// - static OMPTaskwaitDirective * - Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); + static OMPTaskwaitDirective *Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef Clauses); /// Creates an empty directive. /// /// \param C AST context. + /// \param NumClauses Number of clauses. /// - static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell); + static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, EmptyShell); static bool classof(const Stmt *T) { return T->getStmtClass() == OMPTaskwaitDirectiveClass; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10599,6 +10599,8 @@ "unexpected expression: number of expressions is larger than the number of associated loops">; def err_omp_depend_sink_expected_plus_minus : Error< "expected '+' or '-' operation">; +def err_omp_taskwait_depend_mutexinoutset_not_allowed : Error< + "'mutexinoutset' modifier not allowed in 'depend' clause on 'taskwait' directive">; def err_omp_depend_sink_source_not_allowed : Error< "'depend(%select{source|sink:vec}0)' clause%select{|s}0 cannot be mixed with 'depend(%select{sink:vec|source}0)' clause%select{s|}0">; def err_omp_depend_zero_length_array_section_not_allowed : Error< diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -10753,7 +10753,8 @@ StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc); /// Called on well-formed '\#pragma omp taskwait'. - StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, + StmtResult ActOnOpenMPTaskwaitDirective(ArrayRef Clauses, + SourceLocation StartLoc, SourceLocation EndLoc); /// Called on well-formed '\#pragma omp taskgroup'. StmtResult ActOnOpenMPTaskgroupDirective(ArrayRef Clauses, diff --git a/clang/lib/AST/StmtOpenMP.cpp b/clang/lib/AST/StmtOpenMP.cpp --- a/clang/lib/AST/StmtOpenMP.cpp +++ b/clang/lib/AST/StmtOpenMP.cpp @@ -739,15 +739,19 @@ return new (C) OMPBarrierDirective(); } -OMPTaskwaitDirective *OMPTaskwaitDirective::Create(const ASTContext &C, - SourceLocation StartLoc, - SourceLocation EndLoc) { - return new (C) OMPTaskwaitDirective(StartLoc, EndLoc); +OMPTaskwaitDirective * +OMPTaskwaitDirective::Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef Clauses) { + return createDirective( + C, Clauses, /*AssociatedStmt=*/nullptr, /*NumChildren=*/0, StartLoc, + EndLoc); } OMPTaskwaitDirective *OMPTaskwaitDirective::CreateEmpty(const ASTContext &C, + unsigned NumClauses, EmptyShell) { - return new (C) OMPTaskwaitDirective(); + return createEmptyDirective(C, NumClauses); } OMPTaskgroupDirective *OMPTaskgroupDirective::Create( diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.h b/clang/lib/CodeGen/CGOpenMPRuntime.h --- a/clang/lib/CodeGen/CGOpenMPRuntime.h +++ b/clang/lib/CodeGen/CGOpenMPRuntime.h @@ -1547,7 +1547,8 @@ LValue SharedLVal); /// Emit code for 'taskwait' directive. - virtual void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc); + virtual void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc, + const OMPTaskDataTy &Data); /// Emit code for 'cancellation point' construct. /// \param CancelRegion Region kind for which the cancellation point must be @@ -2385,7 +2386,8 @@ LValue SharedLVal) override; /// Emit code for 'taskwait' directive. - void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc) override; + void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc, + const OMPTaskDataTy &Data) override; /// Emit code for 'cancellation point' construct. /// \param CancelRegion Region kind for which the cancellation point must be diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -6264,21 +6264,51 @@ SharedLVal.getAlignment()); } -void CGOpenMPRuntime::emitTaskwaitCall(CodeGenFunction &CGF, - SourceLocation Loc) { +void CGOpenMPRuntime::emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc, + const OMPTaskDataTy &Data) { if (!CGF.HaveInsertPoint()) return; - if (CGF.CGM.getLangOpts().OpenMPIRBuilder) { + if (CGF.CGM.getLangOpts().OpenMPIRBuilder && Data.Dependences.empty()) { + // TODO: Need to support taskwait with dependences in the OpenMPIRBuilder. OMPBuilder.createTaskwait(CGF.Builder); } else { - // Build call kmp_int32 __kmpc_omp_taskwait(ident_t *loc, kmp_int32 - // global_tid); - llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)}; - // Ignore return result until untied tasks are supported. - CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( - CGM.getModule(), OMPRTL___kmpc_omp_taskwait), - Args); + llvm::Value *ThreadID = getThreadID(CGF, Loc); + llvm::Value *UpLoc = emitUpdateLocation(CGF, Loc); + auto &M = CGM.getModule(); + Address DependenciesArray = Address::invalid(); + llvm::Value *NumOfElements; + std::tie(NumOfElements, DependenciesArray) = + emitDependClause(CGF, Data.Dependences, Loc); + llvm::Value *DepWaitTaskArgs[6]; + if (!Data.Dependences.empty()) { + DepWaitTaskArgs[0] = UpLoc; + DepWaitTaskArgs[1] = ThreadID; + DepWaitTaskArgs[2] = NumOfElements; + DepWaitTaskArgs[3] = DependenciesArray.getPointer(); + DepWaitTaskArgs[4] = CGF.Builder.getInt32(0); + DepWaitTaskArgs[5] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy); + + CodeGenFunction::RunCleanupsScope LocalScope(CGF); + + // Build void __kmpc_omp_wait_deps(ident_t *, kmp_int32 gtid, + // kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32 + // ndeps_noalias, kmp_depend_info_t *noalias_dep_list); if dependence info + // is specified. + CGF.EmitRuntimeCall( + OMPBuilder.getOrCreateRuntimeFunction(M, OMPRTL___kmpc_omp_wait_deps), + DepWaitTaskArgs); + + } else { + + // Build call kmp_int32 __kmpc_omp_taskwait(ident_t *loc, kmp_int32 + // global_tid); + llvm::Value *Args[] = {UpLoc, ThreadID}; + // Ignore return result until untied tasks are supported. + CGF.EmitRuntimeCall( + OMPBuilder.getOrCreateRuntimeFunction(M, OMPRTL___kmpc_omp_taskwait), + Args); + } } if (auto *Region = dyn_cast_or_null(CGF.CapturedStmtInfo)) @@ -13044,7 +13074,8 @@ } void CGOpenMPSIMDRuntime::emitTaskwaitCall(CodeGenFunction &CGF, - SourceLocation Loc) { + SourceLocation Loc, + const OMPTaskDataTy &Data) { llvm_unreachable("Not supported in SIMD-only mode"); } diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -4845,7 +4845,14 @@ } void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S) { - CGM.getOpenMPRuntime().emitTaskwaitCall(*this, S.getBeginLoc()); + OMPTaskDataTy Data; + // Build list of dependences + for (const auto *C : S.getClausesOfKind()) { + OMPTaskDataTy::DependData &DD = + Data.Dependences.emplace_back(C->getDependencyKind(), C->getModifier()); + DD.DepExprs.append(C->varlist_begin(), C->varlist_end()); + } + CGM.getOpenMPRuntime().emitTaskwaitCall(*this, S.getBeginLoc(), Data); } void CodeGenFunction::EmitOMPTaskgroupDirective( diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -6046,11 +6046,9 @@ Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); break; case OMPD_taskwait: - assert(ClausesWithImplicit.empty() && - "No clauses are allowed for 'omp taskwait' directive"); assert(AStmt == nullptr && "No associated statement allowed for 'omp taskwait' directive"); - Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); + Res = ActOnOpenMPTaskwaitDirective(ClausesWithImplicit, StartLoc, EndLoc); break; case OMPD_taskgroup: Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, @@ -10467,9 +10465,10 @@ return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); } -StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, +StmtResult Sema::ActOnOpenMPTaskwaitDirective(ArrayRef Clauses, + SourceLocation StartLoc, SourceLocation EndLoc) { - return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); + return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc, Clauses); } StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef Clauses, @@ -18444,6 +18443,11 @@ << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); return nullptr; } + if (DSAStack->getCurrentDirective() == OMPD_taskwait && + DepKind == OMPC_DEPEND_mutexinoutset) { + Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed); + return nullptr; + } if ((DSAStack->getCurrentDirective() != OMPD_ordered || DSAStack->getCurrentDirective() == OMPD_depobj) && (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -2416,6 +2416,8 @@ void ASTStmtReader::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) { VisitStmt(D); + // The NumClauses field was read in ReadStmtFromStream. + Record.skipInts(1); VisitOMPExecutableDirective(D); } @@ -3313,7 +3315,8 @@ break; case STMT_OMP_TASKWAIT_DIRECTIVE: - S = OMPTaskwaitDirective::CreateEmpty(Context, Empty); + S = OMPTaskwaitDirective::CreateEmpty( + Context, Record[ASTStmtReader::NumStmtFields], Empty); break; case STMT_OMP_TASKGROUP_DIRECTIVE: diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -2380,6 +2380,7 @@ void ASTStmtWriter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) { VisitStmt(D); + Record.push_back(D->getNumClauses()); VisitOMPExecutableDirective(D); Code = serialization::STMT_OMP_TASKWAIT_DIRECTIVE; } diff --git a/clang/test/OpenMP/taskwait_ast_print.cpp b/clang/test/OpenMP/taskwait_ast_print.cpp --- a/clang/test/OpenMP/taskwait_ast_print.cpp +++ b/clang/test/OpenMP/taskwait_ast_print.cpp @@ -1,10 +1,10 @@ -// 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 -fsyntax-only -verify %s -ast-print | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s -// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s -// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s // expected-no-diagnostics #ifndef HEADER @@ -16,20 +16,26 @@ T tmain(T argc) { static T a; #pragma omp taskwait +#pragma omp taskwait depend(in:a, argc) return a + argc; } // CHECK: static T a; // CHECK-NEXT: #pragma omp taskwait{{$}} +// CHECK-NEXT: #pragma omp taskwait depend(in : a,argc){{$}} // CHECK: static int a; // CHECK-NEXT: #pragma omp taskwait +// CHECK-NEXT: #pragma omp taskwait depend(in : a,argc){{$}} // CHECK: static char a; // CHECK-NEXT: #pragma omp taskwait +// CHECK-NEXT: #pragma omp taskwait depend(in : a,argc){{$}} int main(int argc, char **argv) { static int a; // CHECK: static int a; #pragma omp taskwait +#pragma omp taskwait depend(out:a, argc) // CHECK-NEXT: #pragma omp taskwait + // CHECK-NEXT: #pragma omp taskwait depend(out : a,argc) return tmain(argc) + tmain(argv[0][0]) + a; } diff --git a/clang/test/OpenMP/taskwait_depend_codegen.cpp b/clang/test/OpenMP/taskwait_depend_codegen.cpp new file mode 100644 --- /dev/null +++ b/clang/test/OpenMP/taskwait_depend_codegen.cpp @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c++ -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s + +// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp-simd -x c++ -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s +// RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-apple-darwin10 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s +// SIMD-ONLY0-NOT: {{__kmpc|__tgt}} +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +void foo() {} + +template +T tmain(T &argc) { + static T a; + #pragma omp taskwait depend(in:argc) + return a + argc; +} +int main(int argc, char **argv) { + int n = 0; + #pragma omp task shared(n,argc) depend(out:n) + n = argc; + return tmain(n); +} + +// CHECK-LABEL: @main +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%{{.+}}* @{{.+}}) +// CHECK: [[ALLOC:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{.+}}* @{{.+}}, i32 [[GTID]], i32 1, i64 40, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{.+}}*)* @{{.+}} to i32 (i32, i8*)*)) +// CHECK: %{{.+}} = call i32 @__kmpc_omp_task_with_deps(%{{.+}}* @{{.+}}, i32 [[GTID]], i8* [[ALLOC]], i32 1, i8* %{{[0-9]*}}, i32 0, i8* null) + +// CHECK-LABEL: tmain +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%{{.+}}* @{{.+}}) +// CHECK: call void @__kmpc_omp_wait_deps(%{{.+}}* @{{.+}}, i32 [[GTID]], i32 1, i8* %{{.}}, i32 0, i8* null) + + +#endif diff --git a/clang/test/OpenMP/taskwait_depend_messages.cpp b/clang/test/OpenMP/taskwait_depend_messages.cpp new file mode 100644 --- /dev/null +++ b/clang/test/OpenMP/taskwait_depend_messages.cpp @@ -0,0 +1,62 @@ +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +class vector { + public: + int operator[](int index) { return 0; } +}; + +int main(int argc, char **argv, char *env[]) { + vector vec; + typedef float V __attribute__((vector_size(16))); + V a; + auto arr = x; // expected-error {{use of undeclared identifier 'x'}} + + #pragma omp taskwait depend // expected-error {{expected '(' after 'depend'}} + #pragma omp taskwait depend ( // expected-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} + #pragma omp taskwait depend () // expected-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} + #pragma omp taskwait depend (argc // expected-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp taskwait depend (source : argc) // expected-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + #pragma omp taskwait depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + #pragma omp taskwait depend(mutexinoutset: argc) // expected-error{{'mutexinoutset' modifier not allowed in 'depend' clause on 'taskwait' directive}} + #pragma omp taskwait depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp taskwait' are ignored}} + #pragma omp taskwait depend (out: ) // expected-error {{expected expression}} + #pragma omp taskwait depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element, array section or array shaping expression}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} + + #pragma omp taskwait depend (out :S1) // expected-error {{'S1' does not refer to a value}} + #pragma omp taskwait depend(in : argv[1][1] = '2') + #pragma omp taskwait depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element, array section or array shaping expression}} + #pragma omp taskwait depend (in : argv[0]) + #pragma omp taskwait depend (in : ) // expected-error {{expected expression}} + #pragma omp taskwait depend (in : main) + #pragma omp taskwait depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element, array section or array shaping expression}} + #pragma omp taskwait depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} + #pragma omp taskwait depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + #pragma omp taskwait depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + #pragma omp taskwait depend (in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp taskwait depend (in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} + #pragma omp taskwait depend (in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp taskwait depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} + #pragma omp taskwait depend (in : argv[-1:0]) // expected-error {{zero-length array section is not allowed in 'depend' clause}} + #pragma omp taskwait depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + #pragma omp taskwait depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + #pragma omp taskwait depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} + #pragma omp taskwait depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}} + #pragma omp taskwait depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + #pragma omp taskwait depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} + #pragma omp taskwait depend(in : argv[ : argc][1 : argc - 1]) + #pragma omp taskwait depend(in : arr[0]) + foo(); + + return 0; +} diff --git a/clang/test/OpenMP/taskwait_messages.cpp b/clang/test/OpenMP/taskwait_messages.cpp --- a/clang/test/OpenMP/taskwait_messages.cpp +++ b/clang/test/OpenMP/taskwait_messages.cpp @@ -1,10 +1,11 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ferror-limit 100 %s -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=45 -ferror-limit 100 %s -Wuninitialized template T tmain(T argc) { #pragma omp taskwait allocate(argc) // expected-error {{unexpected OpenMP clause 'allocate' in directive '#pragma omp taskwait'}} +#pragma omp taskwait depend(in:argc) // expected-error {{unexpected OpenMP clause 'depend' in directive '#pragma omp taskwait'}} ; #pragma omp taskwait untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp taskwait'}} #pragma omp taskwait unknown // expected-warning {{extra tokens at the end of '#pragma omp taskwait' are ignored}} diff --git a/openmp/runtime/test/ompt/tasks/taskwait-depend.c b/openmp/runtime/test/ompt/tasks/taskwait-depend.c --- a/openmp/runtime/test/ompt/tasks/taskwait-depend.c +++ b/openmp/runtime/test/ompt/tasks/taskwait-depend.c @@ -7,10 +7,9 @@ // icc does not yet support taskwait with depend clause // XFAIL: icc -// clang does not yet support taskwait with depend clause -// clang-12 introduced parsing, but no codegen -// update expected result when codegen in clang was added -// XFAIL: clang +// support for taskwait with depend clause introduced in clang-14 +// UNSUPPORTED: clang-5, clang-6, clang-6, clang-8, clang-9, clang-10, clang-11, +// clang-12, clang-13 #include "callback.h" #include diff --git a/openmp/runtime/test/tasking/omp50_taskwait_depend.c b/openmp/runtime/test/tasking/omp50_taskwait_depend.c --- a/openmp/runtime/test/tasking/omp50_taskwait_depend.c +++ b/openmp/runtime/test/tasking/omp50_taskwait_depend.c @@ -1,11 +1,12 @@ // RUN: %libomp-compile-and-run // UNSUPPORTED: gcc-4, gcc-5, gcc-6, gcc-7, gcc-8 -// clang does not yet support taskwait with depend clause -// clang-12 introduced parsing, but no codegen -// TODO: update expected result when codegen in clang is added + +// support for taskwait with depend clause introduced in clang-14 +// UNSUPPORTED: clang-5, clang-6, clang-6, clang-8, clang-9, clang-10, clang-11, +// clang-12, clang-13 + // icc does not yet support taskwait with depend clause -// TODO: update expected result when support for icc is added -// XFAIL: clang, icc +// XFAIL: icc #include #include