Author: Alexey Bataev Date: 2020-02-10T16:01:41-05:00 New Revision: 9559834a5c1286db4e5bc1f5de047bfd67868f4a
URL: https://github.com/llvm/llvm-project/commit/9559834a5c1286db4e5bc1f5de047bfd67868f4a DIFF: https://github.com/llvm/llvm-project/commit/9559834a5c1286db4e5bc1f5de047bfd67868f4a.diff LOG: [OPENMP50]Add support for 'release' clause. Added full support for 'release' clause in flush|atomic directives. Added: Modified: clang/include/clang/AST/OpenMPClause.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Basic/OpenMPKinds.def clang/include/clang/Sema/Sema.h clang/lib/AST/OpenMPClause.cpp clang/lib/AST/StmtProfile.cpp clang/lib/Basic/OpenMPKinds.cpp clang/lib/CodeGen/CGStmtOpenMP.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/test/OpenMP/atomic_ast_print.cpp clang/test/OpenMP/atomic_capture_codegen.cpp clang/test/OpenMP/atomic_messages.cpp clang/test/OpenMP/atomic_read_codegen.c clang/test/OpenMP/atomic_update_codegen.cpp clang/test/OpenMP/atomic_write_codegen.c clang/test/OpenMP/flush_ast_print.cpp clang/test/OpenMP/flush_codegen.cpp clang/test/OpenMP/flush_messages.cpp clang/tools/libclang/CIndex.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index b9c4389ddd63..19a84bd00a36 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -1955,6 +1955,46 @@ class OMPAcquireClause final : public OMPClause { } }; +/// This represents 'release' clause in the '#pragma omp atomic|flush' +/// directives. +/// +/// \code +/// #pragma omp flush release +/// \endcode +/// In this example directive '#pragma omp flush' has 'release' clause. +class OMPReleaseClause final : public OMPClause { +public: + /// Build 'release' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + OMPReleaseClause(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPClause(OMPC_release, StartLoc, EndLoc) {} + + /// Build an empty clause. + OMPReleaseClause() + : OMPClause(OMPC_release, SourceLocation(), SourceLocation()) {} + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_release; + } +}; + /// This represents clause 'private' in the '#pragma omp ...' directives. /// /// \code diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 916fac717dd4..4ef9528dcf5b 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -3131,6 +3131,11 @@ bool RecursiveASTVisitor<Derived>::VisitOMPAcquireClause(OMPAcquireClause *) { return true; } +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPReleaseClause(OMPReleaseClause *) { + return true; +} + template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPThreadsClause(OMPThreadsClause *) { return true; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index cc983f750711..450075f2e927 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -9696,7 +9696,7 @@ def note_omp_atomic_capture: Note< def err_omp_atomic_several_clauses : Error< "directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause">; def err_omp_several_mem_order_clauses : Error< - "directive '#pragma omp %0' cannot contain more than one %select{'seq_cst', |}1'acq_rel' or 'acquire' clause">; + "directive '#pragma omp %0' cannot contain more than one %select{'seq_cst', |}1'acq_rel', 'acquire' or 'release' clause">; def note_omp_previous_mem_order_clause : Note< "'%0' clause used here">; def err_omp_target_contains_not_only_teams : Error< diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def index 346c0f54971d..19fcf7cfac58 100644 --- a/clang/include/clang/Basic/OpenMPKinds.def +++ b/clang/include/clang/Basic/OpenMPKinds.def @@ -259,6 +259,7 @@ OPENMP_CLAUSE(capture, OMPCaptureClause) OPENMP_CLAUSE(seq_cst, OMPSeqCstClause) OPENMP_CLAUSE(acq_rel, OMPAcqRelClause) OPENMP_CLAUSE(acquire, OMPAcquireClause) +OPENMP_CLAUSE(release, OMPReleaseClause) OPENMP_CLAUSE(depend, OMPDependClause) OPENMP_CLAUSE(device, OMPDeviceClause) OPENMP_CLAUSE(threads, OMPThreadsClause) @@ -493,6 +494,7 @@ OPENMP_ATOMIC_CLAUSE(capture) OPENMP_ATOMIC_CLAUSE(seq_cst) OPENMP_ATOMIC_CLAUSE(acq_rel) OPENMP_ATOMIC_CLAUSE(acquire) +OPENMP_ATOMIC_CLAUSE(release) // Clauses allowed for OpenMP directive 'target'. OPENMP_TARGET_CLAUSE(if) @@ -1092,6 +1094,7 @@ OPENMP_ORDER_KIND(concurrent) // Clauses allowed for OpenMP directive 'flush'. OPENMP_FLUSH_CLAUSE(acq_rel) OPENMP_FLUSH_CLAUSE(acquire) +OPENMP_FLUSH_CLAUSE(release) #undef OPENMP_FLUSH_CLAUSE #undef OPENMP_ORDER_KIND diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index beaeccd89820..24cfceda45dc 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -10334,6 +10334,9 @@ class Sema final { /// Called on well-formed 'acquire' clause. OMPClause *ActOnOpenMPAcquireClause(SourceLocation StartLoc, SourceLocation EndLoc); + /// Called on well-formed 'release' clause. + OMPClause *ActOnOpenMPReleaseClause(SourceLocation StartLoc, + SourceLocation EndLoc); /// Called on well-formed 'threads' clause. OMPClause *ActOnOpenMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc); diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index b9156e89173b..2947665981af 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -118,6 +118,7 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) { case OMPC_seq_cst: case OMPC_acq_rel: case OMPC_acquire: + case OMPC_release: case OMPC_depend: case OMPC_threads: case OMPC_simd: @@ -194,6 +195,7 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C) case OMPC_seq_cst: case OMPC_acq_rel: case OMPC_acquire: + case OMPC_release: case OMPC_depend: case OMPC_device: case OMPC_threads: @@ -1346,6 +1348,10 @@ void OMPClausePrinter::VisitOMPAcquireClause(OMPAcquireClause *) { OS << "acquire"; } +void OMPClausePrinter::VisitOMPReleaseClause(OMPReleaseClause *) { + OS << "release"; +} + void OMPClausePrinter::VisitOMPThreadsClause(OMPThreadsClause *) { OS << "threads"; } diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index abe988b80e7b..b303851a75c6 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -522,6 +522,8 @@ void OMPClauseProfiler::VisitOMPAcqRelClause(const OMPAcqRelClause *) {} void OMPClauseProfiler::VisitOMPAcquireClause(const OMPAcquireClause *) {} +void OMPClauseProfiler::VisitOMPReleaseClause(const OMPReleaseClause *) {} + void OMPClauseProfiler::VisitOMPThreadsClause(const OMPThreadsClause *) {} void OMPClauseProfiler::VisitOMPSIMDClause(const OMPSIMDClause *) {} diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 18d97cda71e3..124723552af4 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -216,6 +216,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, case OMPC_seq_cst: case OMPC_acq_rel: case OMPC_acquire: + case OMPC_release: case OMPC_device: case OMPC_threads: case OMPC_simd: @@ -430,6 +431,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, case OMPC_seq_cst: case OMPC_acq_rel: case OMPC_acquire: + case OMPC_release: case OMPC_device: case OMPC_threads: case OMPC_simd: @@ -595,7 +597,8 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, } break; case OMPD_atomic: - if (OpenMPVersion < 50 && (CKind == OMPC_acq_rel || CKind == OMPC_acquire)) + if (OpenMPVersion < 50 && (CKind == OMPC_acq_rel || CKind == OMPC_acquire || + CKind == OMPC_release)) return false; switch (CKind) { #define OPENMP_ATOMIC_CLAUSE(Name) \ diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 433506ff5818..bc71c27fd95f 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -4493,6 +4493,7 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, case OMPC_seq_cst: case OMPC_acq_rel: case OMPC_acquire: + case OMPC_release: case OMPC_shared: case OMPC_linear: case OMPC_aligned: @@ -4546,12 +4547,16 @@ void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) { AO = llvm::AtomicOrdering::AcquireRelease; else if (S.getSingleClause<OMPAcquireClause>()) AO = llvm::AtomicOrdering::Acquire; + else if (S.getSingleClause<OMPReleaseClause>()) + AO = llvm::AtomicOrdering::Release; OpenMPClauseKind Kind = OMPC_unknown; for (const OMPClause *C : S.clauses()) { - // Find first clause (skip seq_cst|acq_rel|aqcuire clause, if it is first). + // Find first clause (skip seq_cst|acq_rel|aqcuire|release clause, if it is + // first). if (C->getClauseKind() != OMPC_seq_cst && C->getClauseKind() != OMPC_acq_rel && - C->getClauseKind() != OMPC_acquire) { + C->getClauseKind() != OMPC_acquire && + C->getClauseKind() != OMPC_release) { Kind = C->getClauseKind(); break; } diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 0214a6afa909..1a7916e5adb8 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -2090,7 +2090,7 @@ bool Parser::ParseOpenMPSimpleVarList( /// nogroup-clause | num_tasks-clause | hint-clause | to-clause | /// from-clause | is_device_ptr-clause | task_reduction-clause | /// in_reduction-clause | allocator-clause | allocate-clause | -/// acq_rel-clause | acquire-clause +/// acq_rel-clause | acquire-clause | release-clause /// OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, bool FirstClause) { @@ -2201,6 +2201,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_seq_cst: case OMPC_acq_rel: case OMPC_acquire: + case OMPC_release: case OMPC_threads: case OMPC_simd: case OMPC_nogroup: diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index ed2320c8ab42..2e3c75fed370 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -4989,6 +4989,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( case OMPC_seq_cst: case OMPC_acq_rel: case OMPC_acquire: + case OMPC_release: case OMPC_depend: case OMPC_threads: case OMPC_simd: @@ -8575,9 +8576,9 @@ StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, OpenMPClauseKind MemOrderKind = OMPC_unknown; SourceLocation MemOrderLoc; for (const OMPClause *C : Clauses) { - if (C->getClauseKind() == OMPC_seq_cst || - C->getClauseKind() == OMPC_acq_rel || - C->getClauseKind() == OMPC_acquire) { + if (C->getClauseKind() == OMPC_acq_rel || + C->getClauseKind() == OMPC_acquire || + C->getClauseKind() == OMPC_release) { if (MemOrderKind != OMPC_unknown) { Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) << getOpenMPDirectiveName(OMPD_flush) << 1 @@ -8953,7 +8954,8 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, } if (C->getClauseKind() == OMPC_seq_cst || C->getClauseKind() == OMPC_acq_rel || - C->getClauseKind() == OMPC_acquire) { + C->getClauseKind() == OMPC_acquire || + C->getClauseKind() == OMPC_release) { if (MemOrderKind != OMPC_unknown) { Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) << getOpenMPDirectiveName(OMPD_atomic) << 0 @@ -10893,6 +10895,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, case OMPC_seq_cst: case OMPC_acq_rel: case OMPC_acquire: + case OMPC_release: case OMPC_depend: case OMPC_threads: case OMPC_simd: @@ -11607,6 +11610,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPC_seq_cst: case OMPC_acq_rel: case OMPC_acquire: + case OMPC_release: case OMPC_depend: case OMPC_threads: case OMPC_simd: @@ -12031,6 +12035,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause( case OMPC_seq_cst: case OMPC_acq_rel: case OMPC_acquire: + case OMPC_release: case OMPC_depend: case OMPC_device: case OMPC_threads: @@ -12233,6 +12238,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( case OMPC_seq_cst: case OMPC_acq_rel: case OMPC_acquire: + case OMPC_release: case OMPC_depend: case OMPC_device: case OMPC_threads: @@ -12412,6 +12418,9 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, case OMPC_acquire: Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); break; + case OMPC_release: + Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); + break; case OMPC_threads: Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); break; @@ -12535,6 +12544,11 @@ OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, return new (Context) OMPAcquireClause(StartLoc, EndLoc); } +OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, + SourceLocation EndLoc) { + return new (Context) OMPReleaseClause(StartLoc, EndLoc); +} + OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc) { return new (Context) OMPThreadsClause(StartLoc, EndLoc); @@ -12693,6 +12707,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause( case OMPC_seq_cst: case OMPC_acq_rel: case OMPC_acquire: + case OMPC_release: case OMPC_device: case OMPC_threads: case OMPC_simd: diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 28ff3fdfc41c..dffaf8938627 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -8818,6 +8818,13 @@ TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) { return C; } +template <typename Derived> +OMPClause * +TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) { + // No need to rebuild this clause, no template-dependent parameters. + return C; +} + template <typename Derived> OMPClause * TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) { diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 89b8e314e8f8..c9553de8143e 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -11672,6 +11672,9 @@ OMPClause *OMPClauseReader::readClause() { case OMPC_acquire: C = new (Context) OMPAcquireClause(); break; + case OMPC_release: + C = new (Context) OMPReleaseClause(); + break; case OMPC_threads: C = new (Context) OMPThreadsClause(); break; @@ -11938,6 +11941,8 @@ void OMPClauseReader::VisitOMPAcqRelClause(OMPAcqRelClause *) {} void OMPClauseReader::VisitOMPAcquireClause(OMPAcquireClause *) {} +void OMPClauseReader::VisitOMPReleaseClause(OMPReleaseClause *) {} + void OMPClauseReader::VisitOMPThreadsClause(OMPThreadsClause *) {} void OMPClauseReader::VisitOMPSIMDClause(OMPSIMDClause *) {} diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 7263e65b4792..eb79ba20ddf7 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -6151,6 +6151,8 @@ void OMPClauseWriter::VisitOMPAcqRelClause(OMPAcqRelClause *) {} void OMPClauseWriter::VisitOMPAcquireClause(OMPAcquireClause *) {} +void OMPClauseWriter::VisitOMPReleaseClause(OMPReleaseClause *) {} + void OMPClauseWriter::VisitOMPThreadsClause(OMPThreadsClause *) {} void OMPClauseWriter::VisitOMPSIMDClause(OMPSIMDClause *) {} diff --git a/clang/test/OpenMP/atomic_ast_print.cpp b/clang/test/OpenMP/atomic_ast_print.cpp index 1cc4289d42f4..4dd64a75f2c9 100644 --- a/clang/test/OpenMP/atomic_ast_print.cpp +++ b/clang/test/OpenMP/atomic_ast_print.cpp @@ -74,6 +74,21 @@ T foo(T argc) { a = b; b++; } +#pragma omp atomic release + a++; +#pragma omp atomic read release + a = argc; +#pragma omp atomic release write + a = argc + argc; +#pragma omp atomic update release + a = a + argc; +#pragma omp atomic release capture + a = b++; +#pragma omp atomic capture release + { + a = b; + b++; + } return T(); } @@ -138,6 +153,21 @@ T foo(T argc) { // CHECK-NEXT: a = b; // CHECK-NEXT: b++; // CHECK-NEXT: } +// CHECK-NEXT: #pragma omp atomic release +// CHECK-NEXT: a++; +// CHECK-NEXT: #pragma omp atomic read release +// CHECK-NEXT: a = argc; +// CHECK-NEXT: #pragma omp atomic release write +// CHECK-NEXT: a = argc + argc; +// CHECK-NEXT: #pragma omp atomic update release +// CHECK-NEXT: a = a + argc; +// CHECK-NEXT: #pragma omp atomic release capture +// CHECK-NEXT: a = b++; +// CHECK-NEXT: #pragma omp atomic capture release +// CHECK-NEXT: { +// CHECK-NEXT: a = b; +// CHECK-NEXT: b++; +// CHECK-NEXT: } // CHECK: int a = int(); // CHECK-NEXT: #pragma omp atomic // CHECK-NEXT: a++; @@ -199,6 +229,21 @@ T foo(T argc) { // CHECK-NEXT: a = b; // CHECK-NEXT: b++; // CHECK-NEXT: } +// CHECK-NEXT: #pragma omp atomic release +// CHECK-NEXT: a++; +// CHECK-NEXT: #pragma omp atomic read release +// CHECK-NEXT: a = argc; +// CHECK-NEXT: #pragma omp atomic release write +// CHECK-NEXT: a = argc + argc; +// CHECK-NEXT: #pragma omp atomic update release +// CHECK-NEXT: a = a + argc; +// CHECK-NEXT: #pragma omp atomic release capture +// CHECK-NEXT: a = b++; +// CHECK-NEXT: #pragma omp atomic capture release +// CHECK-NEXT: { +// CHECK-NEXT: a = b; +// CHECK-NEXT: b++; +// CHECK-NEXT: } int main(int argc, char **argv) { int b = 0; @@ -264,6 +309,21 @@ int main(int argc, char **argv) { a = b; b++; } +#pragma omp atomic release + a++; +#pragma omp atomic read release + a = argc; +#pragma omp atomic release write + a = argc + argc; +#pragma omp atomic update release + a = a + argc; +#pragma omp atomic release capture + a = b++; +#pragma omp atomic capture release + { + a = b; + b++; + } // CHECK-NEXT: #pragma omp atomic // CHECK-NEXT: a++; // CHECK-NEXT: #pragma omp atomic read @@ -324,6 +384,21 @@ int main(int argc, char **argv) { // CHECK-NEXT: a = b; // CHECK-NEXT: b++; // CHECK-NEXT: } + // CHECK-NEXT: #pragma omp atomic release + // CHECK-NEXT: a++; + // CHECK-NEXT: #pragma omp atomic read release + // CHECK-NEXT: a = argc; + // CHECK-NEXT: #pragma omp atomic release write + // CHECK-NEXT: a = argc + argc; + // CHECK-NEXT: #pragma omp atomic update release + // CHECK-NEXT: a = a + argc; + // CHECK-NEXT: #pragma omp atomic release capture + // CHECK-NEXT: a = b++; + // CHECK-NEXT: #pragma omp atomic capture release + // CHECK-NEXT: { + // CHECK-NEXT: a = b; + // CHECK-NEXT: b++; + // CHECK-NEXT: } return foo(a); } diff --git a/clang/test/OpenMP/atomic_capture_codegen.cpp b/clang/test/OpenMP/atomic_capture_codegen.cpp index d3d4e0800ec2..3164c4f419f5 100644 --- a/clang/test/OpenMP/atomic_capture_codegen.cpp +++ b/clang/test/OpenMP/atomic_capture_codegen.cpp @@ -896,14 +896,15 @@ int main() { // CHECK: [[VAL:%.+]] = or i64 [[BF_CLEAR]], [[BF_VALUE]] // CHECK: store i64 [[VAL]], i64* [[TEMP1]] // CHECK: [[NEW_BF_VALUE:%.+]] = load i64, i64* [[TEMP1]] -// CHECK: [[RES:%.+]] = cmpxchg i64* bitcast (%struct.BitFields4* @{{.+}} to i64*), i64 [[OLD_BF_VALUE]], i64 [[NEW_BF_VALUE]] monotonic monotonic +// CHECK: [[RES:%.+]] = cmpxchg i64* bitcast (%struct.BitFields4* @{{.+}} to i64*), i64 [[OLD_BF_VALUE]], i64 [[NEW_BF_VALUE]] release monotonic // CHECK: [[FAILED_OLD_VAL]] = extractvalue { i64, i1 } [[RES]], 0 // CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i64, i1 } [[RES]], 1 // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]] // CHECK: [[EXIT]] // CHECK: [[NEW_VAL:%.+]] = trunc i64 [[CONV]] to i32 // CHECK: store i32 [[NEW_VAL]], i32* @{{.+}}, -#pragma omp atomic capture +// CHECK: call{{.*}} @__kmpc_flush( +#pragma omp atomic capture release {bfx4.b /= ldv; iv = bfx4.b;} // CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}} // CHECK: [[PREV_VALUE:%.+]] = load atomic i8, i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2) acquire diff --git a/clang/test/OpenMP/atomic_messages.cpp b/clang/test/OpenMP/atomic_messages.cpp index 9489eb13fc10..d595689e4d15 100644 --- a/clang/test/OpenMP/atomic_messages.cpp +++ b/clang/test/OpenMP/atomic_messages.cpp @@ -733,7 +733,7 @@ T acq_rel() { // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} // expected-note@+1 {{expected an expression statement}} ; -// omp50-error@+1 2 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'acq_rel' or 'acquire' clause}} omp50-note@+1 2 {{'acq_rel' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}} +// omp50-error@+1 2 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'acq_rel', 'acquire' or 'release' clause}} omp50-note@+1 2 {{'acq_rel' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}} #pragma omp atomic acq_rel seq_cst a += b; @@ -754,7 +754,7 @@ int acq_rel() { // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} // expected-note@+1 {{expected an expression statement}} ; -// omp50-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'acq_rel' or 'acquire' clause}} omp50-note@+1 {{'seq_cst' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}} +// omp50-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'acq_rel', 'acquire' or 'release' clause}} omp50-note@+1 {{'seq_cst' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}} #pragma omp atomic seq_cst acq_rel a += b; @@ -775,7 +775,7 @@ T acquire() { // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} // expected-note@+1 {{expected an expression statement}} ; -// omp50-error@+1 2 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'acq_rel' or 'acquire' clause}} omp50-note@+1 2 {{'acquire' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}} +// omp50-error@+1 2 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'acq_rel', 'acquire' or 'release' clause}} omp50-note@+1 2 {{'acquire' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}} #pragma omp atomic acquire seq_cst a += b; @@ -796,7 +796,7 @@ int acquire() { // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} // expected-note@+1 {{expected an expression statement}} ; -// omp50-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'acq_rel' or 'acquire' clause}} omp50-note@+1 {{'seq_cst' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}} +// omp50-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'acq_rel', 'acquire' or 'release' clause}} omp50-note@+1 {{'seq_cst' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}} #pragma omp atomic seq_cst acquire a += b; @@ -809,6 +809,48 @@ int acquire() { return acquire<int>(); // omp50-note {{in instantiation of function template specialization 'acquire<int>' requested here}} } +template <class T> +T release() { + T a = 0, b = 0; +// omp45-error@+1 {{unexpected OpenMP clause 'release' in directive '#pragma omp atomic'}} +#pragma omp atomic release + // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + ; +// omp50-error@+1 2 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'acq_rel', 'acquire' or 'release' clause}} omp50-note@+1 2 {{'release' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'release' in directive '#pragma omp atomic'}} +#pragma omp atomic release seq_cst + a += b; + +// omp45-error@+1 {{unexpected OpenMP clause 'release' in directive '#pragma omp atomic'}} +#pragma omp atomic update release + // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + ; + + return T(); +} + +int release() { + int a = 0, b = 0; +// Test for atomic release +// omp45-error@+1 {{unexpected OpenMP clause 'release' in directive '#pragma omp atomic'}} +#pragma omp atomic release + // expected-error@+2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + ; +// omp50-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'acq_rel', 'acquire' or 'release' clause}} omp50-note@+1 {{'seq_cst' clause used here}} omp45-error@+1 {{unexpected OpenMP clause 'release' in directive '#pragma omp atomic'}} +#pragma omp atomic seq_cst release + a += b; + +// omp45-error@+1 {{unexpected OpenMP clause 'release' in directive '#pragma omp atomic'}} +#pragma omp atomic update release + // expected-error@+2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}} + // expected-note@+1 {{expected an expression statement}} + ; + + return release<int>(); // omp50-note {{in instantiation of function template specialization 'release<int>' requested here}} +} + template <class T> T mixed() { T a, b = T(); diff --git a/clang/test/OpenMP/atomic_read_codegen.c b/clang/test/OpenMP/atomic_read_codegen.c index 713f370a1012..814975e38ea2 100644 --- a/clang/test/OpenMP/atomic_read_codegen.c +++ b/clang/test/OpenMP/atomic_read_codegen.c @@ -312,7 +312,7 @@ int main() { // CHECK: [[SHL:%.+]] = shl i64 [[LD]], 40 // CHECK: [[ASHR:%.+]] = ashr i64 [[SHL]], 57 // CHECK: store x86_fp80 -#pragma omp atomic read +#pragma omp atomic read release ldv = bfx4.b; // CHECK: [[LD:%.+]] = load atomic i8, i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @bfx4_packed, i32 0, i32 0, i64 2) acquire // CHECK: store i8 [[LD]], i8* [[LDTEMP:%.+]] diff --git a/clang/test/OpenMP/atomic_update_codegen.cpp b/clang/test/OpenMP/atomic_update_codegen.cpp index 31995f7ae8e9..fb900753898c 100644 --- a/clang/test/OpenMP/atomic_update_codegen.cpp +++ b/clang/test/OpenMP/atomic_update_codegen.cpp @@ -529,12 +529,13 @@ int main() { // CHECK: [[DESIRED:%.+]] = zext i1 [[BOOL_DESIRED]] to i8 // CHECK: store i8 [[DESIRED]], i8* [[TEMP:%.+]] // CHECK: [[DESIRED:%.+]] = load i8, i8* [[TEMP]] -// CHECK: [[RES:%.+]] = cmpxchg i8* [[X_ADDR]], i8 [[EXPECTED]], i8 [[DESIRED]] monotonic monotonic +// CHECK: [[RES:%.+]] = cmpxchg i8* [[X_ADDR]], i8 [[EXPECTED]], i8 [[DESIRED]] release monotonic // CHECK: [[OLD_XI8:%.+]] = extractvalue { i8, i1 } [[RES]], 0 // CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i8, i1 } [[RES]], 1 // CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]] // CHECK: [[EXIT]] -#pragma omp atomic update +// CHECK: call{{.*}} @__kmpc_flush( +#pragma omp atomic update release bx = ldv * bx; // CHECK: [[EXPR_RE:%.+]] = load i32, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* [[CIV_ADDR:@.+]], i32 0, i32 0), // CHECK: [[EXPR_IM:%.+]] = load i32, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* [[CIV_ADDR]], i32 0, i32 1), diff --git a/clang/test/OpenMP/atomic_write_codegen.c b/clang/test/OpenMP/atomic_write_codegen.c index c8e8d343252a..f8a74e8c6edd 100644 --- a/clang/test/OpenMP/atomic_write_codegen.c +++ b/clang/test/OpenMP/atomic_write_codegen.c @@ -91,8 +91,8 @@ int main() { #pragma omp atomic write acquire bx = bv; // CHECK: load i8, i8* -// CHECK: store atomic i8 -#pragma omp atomic write +// CHECK: store atomic i8{{.*}}release +#pragma omp atomic write release cx = cv; // CHECK: load i8, i8* // CHECK: store atomic i8 diff --git a/clang/test/OpenMP/flush_ast_print.cpp b/clang/test/OpenMP/flush_ast_print.cpp index bfbe8c3c3268..2f2dbba75c9e 100644 --- a/clang/test/OpenMP/flush_ast_print.cpp +++ b/clang/test/OpenMP/flush_ast_print.cpp @@ -18,6 +18,7 @@ T tmain(T argc) { #pragma omp flush #pragma omp flush acq_rel #pragma omp flush acquire +#pragma omp flush release #pragma omp flush(a) return a + argc; } @@ -25,16 +26,19 @@ T tmain(T argc) { // CHECK-NEXT: #pragma omp flush{{$}} // CHECK-NEXT: #pragma omp flush acq_rel{{$}} // CHECK-NEXT: #pragma omp flush acquire{{$}} +// CHECK-NEXT: #pragma omp flush release{{$}} // CHECK-NEXT: #pragma omp flush (a) // CHECK: static int a; // CHECK-NEXT: #pragma omp flush // CHECK-NEXT: #pragma omp flush acq_rel{{$}} // CHECK-NEXT: #pragma omp flush acquire{{$}} +// CHECK-NEXT: #pragma omp flush release{{$}} // CHECK-NEXT: #pragma omp flush (a) // CHECK: static char a; // CHECK-NEXT: #pragma omp flush // CHECK-NEXT: #pragma omp flush acq_rel{{$}} // CHECK-NEXT: #pragma omp flush acquire{{$}} +// CHECK-NEXT: #pragma omp flush release{{$}} // CHECK-NEXT: #pragma omp flush (a) int main(int argc, char **argv) { @@ -43,10 +47,12 @@ int main(int argc, char **argv) { #pragma omp flush #pragma omp flush acq_rel #pragma omp flush acquire +#pragma omp flush release #pragma omp flush(a) // CHECK-NEXT: #pragma omp flush // CHECK-NEXT: #pragma omp flush acq_rel // CHECK-NEXT: #pragma omp flush acquire{{$}} +// CHECK-NEXT: #pragma omp flush release // CHECK-NEXT: #pragma omp flush (a) return tmain(argc) + tmain(argv[0][0]) + a; } diff --git a/clang/test/OpenMP/flush_codegen.cpp b/clang/test/OpenMP/flush_codegen.cpp index ce66d98ead20..36ab677a7e82 100644 --- a/clang/test/OpenMP/flush_codegen.cpp +++ b/clang/test/OpenMP/flush_codegen.cpp @@ -19,6 +19,7 @@ T tmain(T argc) { #pragma omp flush #pragma omp flush acq_rel #pragma omp flush acquire +#pragma omp flush release #pragma omp flush(a) return a + argc; } @@ -29,11 +30,13 @@ int main() { #pragma omp flush #pragma omp flush acq_rel #pragma omp flush acquire +#pragma omp flush release #pragma omp flush(a) // CHECK: call {{.*}}void @__kmpc_flush(%{{.+}}* {{(@|%).+}}) // CHECK: call {{.*}}void @__kmpc_flush(%{{.+}}* {{(@|%).+}}) // CHECK: call {{.*}}void @__kmpc_flush(%{{.+}}* {{(@|%).+}}) // CHECK: call {{.*}}void @__kmpc_flush(%{{.+}}* {{(@|%).+}}) + // CHECK: call {{.*}}void @__kmpc_flush(%{{.+}}* {{(@|%).+}}) return tmain(a); // CHECK: call {{.*}} [[TMAIN:@.+]]( // CHECK: ret @@ -44,6 +47,7 @@ int main() { // CHECK: call {{.*}}void @__kmpc_flush(%{{.+}}* {{(@|%).+}}) // CHECK: call {{.*}}void @__kmpc_flush(%{{.+}}* {{(@|%).+}}) // CHECK: call {{.*}}void @__kmpc_flush(%{{.+}}* {{(@|%).+}}) +// CHECK: call {{.*}}void @__kmpc_flush(%{{.+}}* {{(@|%).+}}) // CHECK: ret // CHECK-NOT: line: 0, diff --git a/clang/test/OpenMP/flush_messages.cpp b/clang/test/OpenMP/flush_messages.cpp index 9ed08e2ba38e..48a70f3f8dcb 100644 --- a/clang/test/OpenMP/flush_messages.cpp +++ b/clang/test/OpenMP/flush_messages.cpp @@ -137,7 +137,9 @@ label1 : { #pragma omp flush seq_cst // expected-error {{unexpected OpenMP clause 'seq_cst' in directive '#pragma omp flush'}} #pragma omp flush acq_rel // omp45-error {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp flush'}} #pragma omp flush acquire // omp45-error {{unexpected OpenMP clause 'acquire' in directive '#pragma omp flush'}} -#pragma omp flush acq_rel acquire // omp45-error {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp flush'}} omp45-error {{unexpected OpenMP clause 'acquire' in directive '#pragma omp flush'}} omp50-error {{directive '#pragma omp flush' cannot contain more than one 'acq_rel' or 'acquire' clause}} omp50-note {{'acq_rel' clause used here}} +#pragma omp flush release // omp45-error {{unexpected OpenMP clause 'release' in directive '#pragma omp flush'}} +#pragma omp flush acq_rel acquire // omp45-error {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp flush'}} omp45-error {{unexpected OpenMP clause 'acquire' in directive '#pragma omp flush'}} omp50-error {{directive '#pragma omp flush' cannot contain more than one 'acq_rel', 'acquire' or 'release' clause}} omp50-note {{'acq_rel' clause used here}} +#pragma omp flush release acquire // omp45-error {{unexpected OpenMP clause 'release' in directive '#pragma omp flush'}} omp45-error {{unexpected OpenMP clause 'acquire' in directive '#pragma omp flush'}} omp50-error {{directive '#pragma omp flush' cannot contain more than one 'acq_rel', 'acquire' or 'release' clause}} omp50-note {{'release' clause used here}} #pragma omp flush acq_rel (argc) // omp45-error {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp flush'}} omp50-error {{'flush' directive with memory order clause 'acq_rel' cannot have the list}} omp50-note {{memory order clause 'acq_rel' is specified here}} #pragma omp flush(argc) acq_rel // omp45-error {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp flush'}} omp50-error {{'flush' directive with memory order clause 'acq_rel' cannot have the list}} omp50-note {{memory order clause 'acq_rel' is specified here}} return tmain(argc); diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 5dc33bd44548..12479c7abb84 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -23,6 +23,7 @@ #include "clang-c/FatalErrorHandler.h" #include "clang/AST/Attr.h" #include "clang/AST/Mangle.h" +#include "clang/AST/OpenMPClause.h" #include "clang/AST/StmtVisitor.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticCategories.h" @@ -2238,6 +2239,8 @@ void OMPClauseEnqueue::VisitOMPAcqRelClause(const OMPAcqRelClause *) {} void OMPClauseEnqueue::VisitOMPAcquireClause(const OMPAcquireClause *) {} +void OMPClauseEnqueue::VisitOMPReleaseClause(const OMPReleaseClause *) {} + void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {} void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits