Author: abataev Date: Tue Dec 22 06:21:47 2015 New Revision: 256238 URL: http://llvm.org/viewvc/llvm-project?rev=256238&view=rev Log: [OPENMP 4.5] Parsing/sema for 'depend(sink:vec)' clause in 'ordered' directive. OpenMP 4.5 adds 'depend(sink:vec)' in 'ordered' directive for doacross loop synchronization. Patch adds parsing and semantic analysis for this clause.
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/include/clang/Basic/OpenMPKinds.def cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp cfe/trunk/lib/Sema/SemaOpenMP.cpp cfe/trunk/lib/Sema/TreeTransform.h cfe/trunk/test/OpenMP/ordered_ast_print.cpp cfe/trunk/test/OpenMP/ordered_messages.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=256238&r1=256237&r2=256238&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Dec 22 06:21:47 2015 @@ -7951,6 +7951,16 @@ def err_omp_firstprivate_distribute_in_t "reduction variable in '#pragma omp teams' cannot be firstprivate in '#pragma omp distribute'">; def err_omp_depend_clause_thread_simd : Error< "'depend' clauses cannot be mixed with '%0' clause">; +def err_omp_depend_sink_wrong_expr : Error< + "expected expression form x[+-d], where x is the loop iteration variable and d is a constant non-negative integer">; +def err_omp_depend_sink_expected_loop_iteration : Error< + "expected %0 loop iteration variable">; +def err_omp_depend_sink_unexpected_expr : Error< + "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_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">; } // end of OpenMP category let CategoryName = "Related Result Type Issue" in { Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.def?rev=256238&r1=256237&r2=256238&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/OpenMPKinds.def (original) +++ cfe/trunk/include/clang/Basic/OpenMPKinds.def Tue Dec 22 06:21:47 2015 @@ -255,6 +255,7 @@ OPENMP_DEPEND_KIND(in) OPENMP_DEPEND_KIND(out) OPENMP_DEPEND_KIND(inout) OPENMP_DEPEND_KIND(source) +OPENMP_DEPEND_KIND(sink) // Modifiers for 'linear' clause. OPENMP_LINEAR_KIND(val) Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=256238&r1=256237&r2=256238&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Tue Dec 22 06:21:47 2015 @@ -7760,8 +7760,10 @@ private: /// \brief Initialization of data-sharing attributes stack. void InitDataSharingAttributesStack(); void DestroyDataSharingAttributesStack(); - ExprResult VerifyPositiveIntegerConstantInClause(Expr *Op, - OpenMPClauseKind CKind); + ExprResult + VerifyPositiveIntegerConstantInClause(Expr *Op, OpenMPClauseKind CKind, + bool StrictlyPositive = true); + public: /// \brief Return true if the provided declaration \a VD should be captured by /// reference in the provided scope \a RSI. This will take into account the Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp?rev=256238&r1=256237&r2=256238&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp (original) +++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp Tue Dec 22 06:21:47 2015 @@ -2556,6 +2556,7 @@ void CGOpenMPRuntime::emitTaskCall( DepKind = DepInOut; break; case OMPC_DEPEND_source: + case OMPC_DEPEND_sink: case OMPC_DEPEND_unknown: llvm_unreachable("Unknown task dependence type"); } Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=256238&r1=256237&r2=256238&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original) +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Tue Dec 22 06:21:47 2015 @@ -89,7 +89,7 @@ private: }; typedef llvm::SmallDenseMap<VarDecl *, DSAInfo, 64> DeclSAMapTy; typedef llvm::SmallDenseMap<VarDecl *, DeclRefExpr *, 64> AlignedMapTy; - typedef llvm::DenseSet<VarDecl *> LoopControlVariablesSetTy; + typedef llvm::DenseMap<VarDecl *, unsigned> LoopControlVariablesMapTy; typedef llvm::SmallDenseMap<VarDecl *, MapInfo, 64> MappedDeclsTy; typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>> CriticalsWithHintsTy; @@ -98,7 +98,7 @@ private: DeclSAMapTy SharingMap; AlignedMapTy AlignedMap; MappedDeclsTy MappedDecls; - LoopControlVariablesSetTy LCVSet; + LoopControlVariablesMapTy LCVMap; DefaultDataSharingAttributes DefaultAttr; SourceLocation DefaultAttrLoc; OpenMPDirectiveKind Directive; @@ -115,12 +115,12 @@ private: SourceLocation InnerTeamsRegionLoc; SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, Scope *CurScope, SourceLocation Loc) - : SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified), + : SharingMap(), AlignedMap(), LCVMap(), DefaultAttr(DSA_unspecified), Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope), ConstructLoc(Loc), OrderedRegion(), NowaitRegion(false), CancelRegion(false), CollapseNumber(1), InnerTeamsRegionLoc() {} SharingMapTy() - : SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified), + : SharingMap(), AlignedMap(), LCVMap(), DefaultAttr(DSA_unspecified), Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr), ConstructLoc(), OrderedRegion(), NowaitRegion(false), CancelRegion(false), CollapseNumber(1), InnerTeamsRegionLoc() {} @@ -185,7 +185,17 @@ public: void addLoopControlVariable(VarDecl *D); /// \brief Check if the specified variable is a loop control variable for /// current region. - bool isLoopControlVariable(VarDecl *D); + /// \return The index of the loop control variable in the list of associated + /// for-loops (from outer to inner). + unsigned isLoopControlVariable(VarDecl *D); + /// \brief Check if the specified variable is a loop control variable for + /// parent region. + /// \return The index of the loop control variable in the list of associated + /// for-loops (from outer to inner). + unsigned isParentLoopControlVariable(VarDecl *D); + /// \brief Get the loop control variable for the I-th loop (or nullptr) in + /// parent directive. + VarDecl *getParentLoopControlVariable(unsigned I); /// \brief Adds explicit data sharing attribute to the specified declaration. void addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A); @@ -486,13 +496,32 @@ DeclRefExpr *DSAStackTy::addUniqueAligne void DSAStackTy::addLoopControlVariable(VarDecl *D) { assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); D = D->getCanonicalDecl(); - Stack.back().LCVSet.insert(D); + Stack.back().LCVMap[D] = Stack.back().LCVMap.size() + 1; } -bool DSAStackTy::isLoopControlVariable(VarDecl *D) { +unsigned DSAStackTy::isLoopControlVariable(VarDecl *D) { assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); D = D->getCanonicalDecl(); - return Stack.back().LCVSet.count(D) > 0; + return Stack.back().LCVMap.count(D) > 0 ? Stack.back().LCVMap[D] : 0; +} + +unsigned DSAStackTy::isParentLoopControlVariable(VarDecl *D) { + assert(Stack.size() > 2 && "Data-sharing attributes stack is empty"); + D = D->getCanonicalDecl(); + return Stack[Stack.size() - 2].LCVMap.count(D) > 0 + ? Stack[Stack.size() - 2].LCVMap[D] + : 0; +} + +VarDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) { + assert(Stack.size() > 2 && "Data-sharing attributes stack is empty"); + if (Stack[Stack.size() - 2].LCVMap.size() < I) + return nullptr; + for (auto &Pair : Stack[Stack.size() - 2].LCVMap) { + if (Pair.second == I) + return Pair.first; + } + return nullptr; } void DSAStackTy::addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A) { @@ -4576,6 +4605,7 @@ StmtResult Sema::ActOnOpenMPOrderedDirec SourceLocation EndLoc) { OMPClause *DependFound = nullptr; OMPClause *DependSourceClause = nullptr; + OMPClause *DependSinkClause = nullptr; bool ErrorFound = false; OMPThreadsClause *TC = nullptr; OMPSIMDClause *SC = nullptr; @@ -4590,6 +4620,18 @@ StmtResult Sema::ActOnOpenMPOrderedDirec ErrorFound = true; } else DependSourceClause = C; + if (DependSinkClause) { + Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed) + << 0; + ErrorFound = true; + } + } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { + if (DependSourceClause) { + Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed) + << 1; + ErrorFound = true; + } + DependSinkClause = C; } } else if (C->getClauseKind() == OMPC_threads) TC = cast<OMPThreadsClause>(C); @@ -5753,7 +5795,8 @@ OMPClause *Sema::ActOnOpenMPNumThreadsCl } ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, - OpenMPClauseKind CKind) { + OpenMPClauseKind CKind, + bool StrictlyPositive) { if (!E) return ExprError(); if (E->isValueDependent() || E->isTypeDependent() || @@ -5763,9 +5806,11 @@ ExprResult Sema::VerifyPositiveIntegerCo ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); if (ICE.isInvalid()) return ExprError(); - if (!Result.isStrictlyPositive()) { + if ((StrictlyPositive && !Result.isStrictlyPositive()) || + (!StrictlyPositive && !Result.isNonNegative())) { Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) - << getOpenMPClauseName(CKind) << 1 << E->getSourceRange(); + << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) + << E->getSourceRange(); return ExprError(); } if (CKind == OMPC_aligned && !Result.isPowerOf2()) { @@ -7990,29 +8035,32 @@ Sema::ActOnOpenMPDependClause(OpenMPDepe ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { if (DSAStack->getCurrentDirective() == OMPD_ordered && - DepKind != OMPC_DEPEND_source) { + DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { std::string Values = "'"; Values += getOpenMPSimpleClauseTypeName(OMPC_depend, OMPC_DEPEND_source); + Values += "' or '"; + Values += getOpenMPSimpleClauseTypeName(OMPC_depend, OMPC_DEPEND_sink); Values += "'"; Diag(DepLoc, diag::err_omp_unexpected_clause_value) << Values << getOpenMPClauseName(OMPC_depend); return nullptr; } if (DSAStack->getCurrentDirective() != OMPD_ordered && - (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source)) { + (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || + DepKind == OMPC_DEPEND_sink)) { std::string Values; std::string Sep(", "); for (unsigned i = 0; i < OMPC_DEPEND_unknown; ++i) { - if (i == OMPC_DEPEND_source) + if (i == OMPC_DEPEND_source || i == OMPC_DEPEND_sink) continue; Values += "'"; Values += getOpenMPSimpleClauseTypeName(OMPC_depend, i); Values += "'"; switch (i) { - case OMPC_DEPEND_unknown - 3: + case OMPC_DEPEND_unknown - 4: Values += " or "; break; - case OMPC_DEPEND_unknown - 2: + case OMPC_DEPEND_unknown - 3: break; default: Values += Sep; @@ -8024,38 +8072,128 @@ Sema::ActOnOpenMPDependClause(OpenMPDepe return nullptr; } SmallVector<Expr *, 8> Vars; - for (auto &RefExpr : VarList) { - assert(RefExpr && "NULL expr in OpenMP shared clause."); - if (isa<DependentScopeDeclRefExpr>(RefExpr)) { - // It will be analyzed later. - Vars.push_back(RefExpr); - continue; - } + llvm::APSInt DepCounter(/*BitWidth=*/32); + llvm::APSInt TotalDepCount(/*BitWidth=*/32); + if (DepKind == OMPC_DEPEND_sink) { + if (auto *OrderedCountExpr = DSAStack->getParentOrderedRegionParam()) { + TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); + TotalDepCount.setIsUnsigned(/*Val=*/true); + } + } + if ((DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) || + DSAStack->getParentOrderedRegionParam()) { + for (auto &RefExpr : VarList) { + assert(RefExpr && "NULL expr in OpenMP shared clause."); + if (isa<DependentScopeDeclRefExpr>(RefExpr) || + (DepKind == OMPC_DEPEND_sink && CurContext->isDependentContext())) { + // It will be analyzed later. + Vars.push_back(RefExpr); + continue; + } - SourceLocation ELoc = RefExpr->getExprLoc(); - // OpenMP [2.11.1.1, Restrictions, p.3] - // A variable that is part of another variable (such as a field of a - // structure) but is not an array element or an array section cannot appear - // in a depend clause. - auto *SimpleExpr = RefExpr->IgnoreParenCasts(); - auto *DE = dyn_cast<DeclRefExpr>(SimpleExpr); - auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); - auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); - if (!RefExpr->IgnoreParenImpCasts()->isLValue() || - (!ASE && !DE && !OASE) || (DE && !isa<VarDecl>(DE->getDecl())) || - (ASE && !ASE->getBase()->getType()->isAnyPointerType() && - !ASE->getBase()->getType()->isArrayType())) { - Diag(ELoc, diag::err_omp_expected_var_name_or_array_item) - << RefExpr->getSourceRange(); - continue; + SourceLocation ELoc = RefExpr->getExprLoc(); + auto *SimpleExpr = RefExpr->IgnoreParenCasts(); + if (DepKind == OMPC_DEPEND_sink) { + if (DepCounter >= TotalDepCount) { + Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); + continue; + } + ++DepCounter; + // OpenMP [2.13.9, Summary] + // depend(dependence-type : vec), where dependence-type is: + // 'sink' and where vec is the iteration vector, which has the form: + // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] + // where n is the value specified by the ordered clause in the loop + // directive, xi denotes the loop iteration variable of the i-th nested + // loop associated with the loop directive, and di is a constant + // non-negative integer. + SimpleExpr = SimpleExpr->IgnoreImplicit(); + auto *DE = dyn_cast<DeclRefExpr>(SimpleExpr); + if (!DE) { + OverloadedOperatorKind OOK = OO_None; + SourceLocation OOLoc; + Expr *LHS, *RHS; + if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { + OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); + OOLoc = BO->getOperatorLoc(); + LHS = BO->getLHS()->IgnoreParenImpCasts(); + RHS = BO->getRHS()->IgnoreParenImpCasts(); + } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { + OOK = OCE->getOperator(); + OOLoc = OCE->getOperatorLoc(); + LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); + RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); + } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { + OOK = MCE->getMethodDecl() + ->getNameInfo() + .getName() + .getCXXOverloadedOperator(); + OOLoc = MCE->getCallee()->getExprLoc(); + LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); + RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); + } else { + Diag(ELoc, diag::err_omp_depend_sink_wrong_expr); + continue; + } + DE = dyn_cast<DeclRefExpr>(LHS); + if (!DE) { + Diag(LHS->getExprLoc(), + diag::err_omp_depend_sink_expected_loop_iteration) + << DSAStack->getParentLoopControlVariable( + DepCounter.getZExtValue()); + continue; + } + if (OOK != OO_Plus && OOK != OO_Minus) { + Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); + continue; + } + ExprResult Res = VerifyPositiveIntegerConstantInClause( + RHS, OMPC_depend, /*StrictlyPositive=*/false); + if (Res.isInvalid()) + continue; + } + auto *VD = dyn_cast<VarDecl>(DE->getDecl()); + if (!CurContext->isDependentContext() && + DSAStack->getParentOrderedRegionParam() && + (!VD || DepCounter != DSAStack->isParentLoopControlVariable(VD))) { + Diag(DE->getExprLoc(), + diag::err_omp_depend_sink_expected_loop_iteration) + << DSAStack->getParentLoopControlVariable( + DepCounter.getZExtValue()); + continue; + } + } else { + // OpenMP [2.11.1.1, Restrictions, p.3] + // A variable that is part of another variable (such as a field of a + // structure) but is not an array element or an array section cannot + // appear in a depend clause. + auto *DE = dyn_cast<DeclRefExpr>(SimpleExpr); + auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); + auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); + if (!RefExpr->IgnoreParenImpCasts()->isLValue() || + (!ASE && !DE && !OASE) || (DE && !isa<VarDecl>(DE->getDecl())) || + (ASE && !ASE->getBase()->getType()->isAnyPointerType() && + !ASE->getBase()->getType()->isArrayType())) { + Diag(ELoc, diag::err_omp_expected_var_name_or_array_item) + << RefExpr->getSourceRange(); + continue; + } + } + + Vars.push_back(RefExpr->IgnoreParenImpCasts()); } - Vars.push_back(RefExpr->IgnoreParenImpCasts()); + if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && + TotalDepCount > VarList.size() && + DSAStack->getParentOrderedRegionParam()) { + Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) + << DSAStack->getParentLoopControlVariable(VarList.size() + 1); + } + if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && + Vars.empty()) + return nullptr; } - if (DepKind != OMPC_DEPEND_source && Vars.empty()) - return nullptr; - return OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, DepKind, DepLoc, ColonLoc, Vars); } Modified: cfe/trunk/lib/Sema/TreeTransform.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=256238&r1=256237&r2=256238&view=diff ============================================================================== --- cfe/trunk/lib/Sema/TreeTransform.h (original) +++ cfe/trunk/lib/Sema/TreeTransform.h Tue Dec 22 06:21:47 2015 @@ -6275,6 +6275,11 @@ TreeTransform<Derived>::TransformForStmt if (Init.isInvalid()) return StmtError(); + // In OpenMP loop region loop control variable must be captured and be + // private. Perform analysis of first part (if any). + if (getSema().getLangOpts().OpenMP && Init.isUsable()) + getSema().ActOnOpenMPLoopInitialization(S->getForLoc(), Init.get()); + // Transform the condition ExprResult Cond; VarDecl *ConditionVar = nullptr; Modified: cfe/trunk/test/OpenMP/ordered_ast_print.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/ordered_ast_print.cpp?rev=256238&r1=256237&r2=256238&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/ordered_ast_print.cpp (original) +++ cfe/trunk/test/OpenMP/ordered_ast_print.cpp Tue Dec 22 06:21:47 2015 @@ -8,7 +8,7 @@ void foo() {} -template <class T> +template <class T, int N> T tmain (T argc) { T b = argc, c, d, e, f, g; static T a; @@ -45,6 +45,7 @@ T tmain (T argc) { #pragma omp parallel for ordered(1) for (int i =0 ; i < argc; ++i) { #pragma omp ordered depend(source) + #pragma omp ordered depend(sink:i+N) a = 2; } return (0); @@ -84,6 +85,7 @@ T tmain (T argc) { // CHECK-NEXT: #pragma omp parallel for ordered(1) // CHECK-NEXT: for (int i = 0; i < argc; ++i) { // CHECK-NEXT: #pragma omp ordered depend(source) +// CHECK-NEXT: #pragma omp ordered depend(sink : i + 3) // CHECK-NEXT: a = 2; // CHECK-NEXT: } // CHECK: static T a; @@ -120,6 +122,7 @@ T tmain (T argc) { // CHECK-NEXT: #pragma omp parallel for ordered(1) // CHECK-NEXT: for (int i = 0; i < argc; ++i) { // CHECK-NEXT: #pragma omp ordered depend(source) +// CHECK-NEXT: #pragma omp ordered depend(sink : i + N) // CHECK-NEXT: a = 2; // CHECK-NEXT: } @@ -161,6 +164,7 @@ int main (int argc, char **argv) { #pragma omp parallel for ordered(1) for (int i =0 ; i < argc; ++i) { #pragma omp ordered depend(source) + #pragma omp ordered depend(sink: i - 5) a = 2; } // CHECK-NEXT: #pragma omp for ordered @@ -196,9 +200,10 @@ int main (int argc, char **argv) { // CHECK-NEXT: #pragma omp parallel for ordered(1) // CHECK-NEXT: for (int i = 0; i < argc; ++i) { // CHECK-NEXT: #pragma omp ordered depend(source) +// CHECK-NEXT: #pragma omp ordered depend(sink : i - 5) // CHECK-NEXT: a = 2; // CHECK-NEXT: } - return tmain(argc); + return tmain<int, 3>(argc); } #endif Modified: cfe/trunk/test/OpenMP/ordered_messages.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/ordered_messages.cpp?rev=256238&r1=256237&r2=256238&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/ordered_messages.cpp (original) +++ cfe/trunk/test/OpenMP/ordered_messages.cpp Tue Dec 22 06:21:47 2015 @@ -4,6 +4,7 @@ int foo(); template <class T> T foo() { + T k; #pragma omp for ordered for (int i = 0; i < 10; ++i) { L1: @@ -95,28 +96,44 @@ T foo() { #pragma omp parallel for ordered for (int i = 0; i < 10; ++i) { #pragma omp ordered depend(source) // expected-error {{'ordered' directive with 'depend' clause cannot be closely nested inside ordered region without specified parameter}} + #pragma omp ordered depend(sink : i) // expected-error {{'ordered' directive with 'depend' clause cannot be closely nested inside ordered region without specified parameter}} } -#pragma omp parallel for ordered(1) // expected-note 3 {{'ordered' clause with specified parameter}} +#pragma omp parallel for ordered(2) // expected-note 5 {{'ordered' clause with specified parameter}} for (int i = 0; i < 10; ++i) { for (int j = 0; j < 10; ++j) { #pragma omp ordered depend // expected-error {{expected '(' after 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} -#pragma omp ordered depend( // expected-error {{expected ')'}} expected-error {{expected 'source' in OpenMP clause 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} expected-warning {{missing ':' or ')' after dependency type - ignoring}} expected-note {{to match this '('}} +#pragma omp ordered depend( // expected-error {{expected ')'}} expected-error {{expected 'source' or 'sink' in OpenMP clause 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} expected-warning {{missing ':' or ')' after dependency type - ignoring}} expected-note {{to match this '('}} #pragma omp ordered depend(source // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp ordered depend(sink // expected-error {{expected expression}} expected-warning {{missing ':' or ')' after dependency type - ignoring}} expected-error {{expected ')'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} expected-note {{to match this '('}} +#pragma omp ordered depend(sink : // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} +#pragma omp ordered depend(sink : i // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'j' loop iteration variable}} +#pragma omp ordered depend(sink : i) // expected-error {{expected 'j' loop iteration variable}} #pragma omp ordered depend(source) if (i == j) #pragma omp ordered depend(source) // expected-error {{'#pragma omp ordered' with 'depend' clause cannot be an immediate substatement}} ; + if (i == j) +#pragma omp ordered depend(sink : i, j) // expected-error {{'#pragma omp ordered' with 'depend' clause cannot be an immediate substatement}} + ; #pragma omp ordered depend(source) threads // expected-error {{'depend' clauses cannot be mixed with 'threads' clause}} #pragma omp ordered simd depend(source) // expected-error {{'depend' clauses cannot be mixed with 'simd' clause}} #pragma omp ordered depend(source) depend(source) // expected-error {{directive '#pragma omp ordered' cannot contain more than one 'depend' clause with 'source' dependence}} -#pragma omp ordered depend(in : i) // expected-error {{expected 'source' in OpenMP clause 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} +#pragma omp ordered depend(in : i) // expected-error {{expected 'source' or 'sink' in OpenMP clause 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} +#pragma omp ordered depend(sink : i, j) +#pragma omp ordered depend(sink : j, i) // expected-error {{expected 'i' loop iteration variable}} expected-error {{expected 'j' loop iteration variable}} +#pragma omp ordered depend(sink : i, j, k) // expected-error {{unexpected expression: number of expressions is larger than the number of associated loops}} +#pragma omp ordered depend(sink : i+foo(), j/4) // expected-error {{expression is not an integral constant expression}} expected-error {{expected '+' or '-' operation}} +#pragma omp ordered depend(sink : i*0, j-4)// expected-error {{expected '+' or '-' operation}} +#pragma omp ordered depend(sink : i-0, j+sizeof(T)) depend(sink : i-0, j+sizeof(T)) +#pragma omp ordered depend(sink : i-0, j+sizeof(T)) depend(source) // expected-error {{'depend(source)' clause cannot be mixed with 'depend(sink:vec)' clauses}} +#pragma omp ordered depend(source) depend(sink : i-0, j+sizeof(T)) // expected-error {{'depend(sink:vec)' clauses cannot be mixed with 'depend(source)' clause}} } } - return T(); } int foo() { +int k; #pragma omp for ordered for (int i = 0; i < 10; ++i) { L1: @@ -208,23 +225,39 @@ int foo() { #pragma omp parallel for ordered for (int i = 0; i < 10; ++i) { #pragma omp ordered depend(source) // expected-error {{'ordered' directive with 'depend' clause cannot be closely nested inside ordered region without specified parameter}} + #pragma omp ordered depend(sink : i) // expected-error {{'ordered' directive with 'depend' clause cannot be closely nested inside ordered region without specified parameter}} } -#pragma omp parallel for ordered(1) // expected-note 3 {{'ordered' clause with specified parameter}} +#pragma omp parallel for ordered(2) // expected-note 5 {{'ordered' clause with specified parameter}} for (int i = 0; i < 10; ++i) { for (int j = 0; j < 10; ++j) { #pragma omp ordered depend // expected-error {{expected '(' after 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} -#pragma omp ordered depend( // expected-error {{expected ')'}} expected-error {{expected 'source' in OpenMP clause 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} expected-warning {{missing ':' or ')' after dependency type - ignoring}} expected-note {{to match this '('}} +#pragma omp ordered depend( // expected-error {{expected ')'}} expected-error {{expected 'source' or 'sink' in OpenMP clause 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} expected-warning {{missing ':' or ')' after dependency type - ignoring}} expected-note {{to match this '('}} #pragma omp ordered depend(source // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp ordered depend(sink // expected-error {{expected expression}} expected-warning {{missing ':' or ')' after dependency type - ignoring}} expected-error {{expected ')'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} expected-note {{to match this '('}} +#pragma omp ordered depend(sink : // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} +#pragma omp ordered depend(sink : i // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'j' loop iteration variable}} +#pragma omp ordered depend(sink : i) // expected-error {{expected 'j' loop iteration variable}} #pragma omp ordered depend(source) if (i == j) #pragma omp ordered depend(source) // expected-error {{'#pragma omp ordered' with 'depend' clause cannot be an immediate substatement}} ; + if (i == j) +#pragma omp ordered depend(sink : i, j) // expected-error {{'#pragma omp ordered' with 'depend' clause cannot be an immediate substatement}} + ; #pragma omp ordered depend(source) threads // expected-error {{'depend' clauses cannot be mixed with 'threads' clause}} #pragma omp ordered simd depend(source) // expected-error {{'depend' clauses cannot be mixed with 'simd' clause}} #pragma omp ordered depend(source) depend(source) // expected-error {{directive '#pragma omp ordered' cannot contain more than one 'depend' clause with 'source' dependence}} -#pragma omp ordered depend(in : i) // expected-error {{expected 'source' in OpenMP clause 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} +#pragma omp ordered depend(in : i) // expected-error {{expected 'source' or 'sink' in OpenMP clause 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} +#pragma omp ordered depend(sink : i, j) +#pragma omp ordered depend(sink : j, i) // expected-error {{expected 'i' loop iteration variable}} expected-error {{expected 'j' loop iteration variable}} +#pragma omp ordered depend(sink : i, j, k) // expected-error {{unexpected expression: number of expressions is larger than the number of associated loops}} +#pragma omp ordered depend(sink : i+foo(), j/4) // expected-error {{expression is not an integral constant expression}} expected-error {{expected '+' or '-' operation}} +#pragma omp ordered depend(sink : i*0, j-4)// expected-error {{expected '+' or '-' operation}} +#pragma omp ordered depend(sink : i-0, j+sizeof(int)) depend(sink : i-0, j+sizeof(int)) +#pragma omp ordered depend(sink : i-0, j+sizeof(int)) depend(source) // expected-error {{'depend(source)' clause cannot be mixed with 'depend(sink:vec)' clauses}} +#pragma omp ordered depend(source) depend(sink : i-0, j+sizeof(int)) // expected-error {{'depend(sink:vec)' clauses cannot be mixed with 'depend(source)' clause}} } } - return foo<int>(); + return foo<int>(); // expected-note {{in instantiation of function template specialization 'foo<int>' requested here}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits