diff options
| author | Alexey Bataev <a.bataev@hotmail.com> | 2015-08-21 11:14:16 +0000 |
|---|---|---|
| committer | Alexey Bataev <a.bataev@hotmail.com> | 2015-08-21 11:14:16 +0000 |
| commit | 66b15b505fe1af2eb570e35a98b3acbd4b6d38e5 (patch) | |
| tree | d544c8df86cb5a2ed9132b5011e17a8ad48c3731 | |
| parent | b3b1f467cea319c24ce5065881b874fa5afe4cb6 (diff) | |
| download | bcm5719-llvm-66b15b505fe1af2eb570e35a98b3acbd4b6d38e5.tar.gz bcm5719-llvm-66b15b505fe1af2eb570e35a98b3acbd4b6d38e5.zip | |
[OPENMP 4.1] Initial support for 'simdlen' clause.
Add parsing/sema analysis for 'simdlen' clause in simd directives. Also add check that if both 'safelen' and 'simdlen' clauses are specified, the value of 'simdlen' parameter is less than the value of 'safelen' parameter.
llvm-svn: 245692
25 files changed, 787 insertions, 27 deletions
diff --git a/clang/include/clang/AST/DataRecursiveASTVisitor.h b/clang/include/clang/AST/DataRecursiveASTVisitor.h index 5a6952f321d..e06e67a4690 100644 --- a/clang/include/clang/AST/DataRecursiveASTVisitor.h +++ b/clang/include/clang/AST/DataRecursiveASTVisitor.h @@ -2455,6 +2455,12 @@ bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) { } template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPSimdlenClause(OMPSimdlenClause *C) { + TRY_TO(TraverseStmt(C->getSimdlen())); + return true; +} + +template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPCollapseClause(OMPCollapseClause *C) { TRY_TO(TraverseStmt(C->getNumForLoops())); diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index b9be9f6c1a8..40ac7fa5136 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -365,6 +365,61 @@ public: child_range children() { return child_range(&Safelen, &Safelen + 1); } }; +/// \brief This represents 'simdlen' clause in the '#pragma omp ...' +/// directive. +/// +/// \code +/// #pragma omp simd simdlen(4) +/// \endcode +/// In this example directive '#pragma omp simd' has clause 'simdlen' +/// with single expression '4'. +/// If the 'simdlen' clause is used then it specifies the preferred number of +/// iterations to be executed concurrently. The parameter of the 'simdlen' +/// clause must be a constant positive integer expression. +/// +class OMPSimdlenClause : public OMPClause { + friend class OMPClauseReader; + /// \brief Location of '('. + SourceLocation LParenLoc; + /// \brief Safe iteration space distance. + Stmt *Simdlen; + + /// \brief Set simdlen. + void setSimdlen(Expr *Len) { Simdlen = Len; } + +public: + /// \brief Build 'simdlen' clause. + /// + /// \param Len Expression associated with this clause. + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + /// + OMPSimdlenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPClause(OMPC_simdlen, StartLoc, EndLoc), LParenLoc(LParenLoc), + Simdlen(Len) {} + + /// \brief Build an empty clause. + /// + explicit OMPSimdlenClause() + : OMPClause(OMPC_simdlen, SourceLocation(), SourceLocation()), + LParenLoc(SourceLocation()), Simdlen(nullptr) {} + + /// \brief Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + /// \brief Return safe iteration space distance. + Expr *getSimdlen() const { return cast_or_null<Expr>(Simdlen); } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_simdlen; + } + + child_range children() { return child_range(&Simdlen, &Simdlen + 1); } +}; + /// \brief This represents 'collapse' clause in the '#pragma omp ...' /// directive. /// diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 61e61a9b7bd..6c8d6e125f5 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2487,6 +2487,12 @@ bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) { } template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPSimdlenClause(OMPSimdlenClause *C) { + TRY_TO(TraverseStmt(C->getSimdlen())); + return true; +} + +template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPCollapseClause(OMPCollapseClause *C) { TRY_TO(TraverseStmt(C->getNumForLoops())); diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 43a51f4335d..f386915eed9 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7671,6 +7671,8 @@ def err_omp_wrong_linear_modifier : Error< "expected %select{'val' modifier|one of 'ref', val' or 'uval' modifiers}0">; def err_omp_wrong_linear_modifier_non_reference : Error< "variable of non-reference type %0 can be used only with 'val' modifier, but used with '%1'">; +def err_omp_wrong_simdlen_safelen_values : Error< + "the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter">; } // end of OpenMP category let CategoryName = "Related Result Type Issue" in { diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def index 11e18f57b3c..1d274c84c94 100644 --- a/clang/include/clang/Basic/OpenMPKinds.def +++ b/clang/include/clang/Basic/OpenMPKinds.def @@ -112,6 +112,7 @@ OPENMP_CLAUSE(if, OMPIfClause) OPENMP_CLAUSE(final, OMPFinalClause) OPENMP_CLAUSE(num_threads, OMPNumThreadsClause) OPENMP_CLAUSE(safelen, OMPSafelenClause) +OPENMP_CLAUSE(simdlen, OMPSimdlenClause) OPENMP_CLAUSE(collapse, OMPCollapseClause) OPENMP_CLAUSE(default, OMPDefaultClause) OPENMP_CLAUSE(private, OMPPrivateClause) @@ -155,6 +156,7 @@ OPENMP_SIMD_CLAUSE(lastprivate) OPENMP_SIMD_CLAUSE(linear) OPENMP_SIMD_CLAUSE(aligned) OPENMP_SIMD_CLAUSE(safelen) +OPENMP_SIMD_CLAUSE(simdlen) OPENMP_SIMD_CLAUSE(collapse) OPENMP_SIMD_CLAUSE(reduction) @@ -178,6 +180,7 @@ OPENMP_FOR_SIMD_CLAUSE(schedule) OPENMP_FOR_SIMD_CLAUSE(collapse) OPENMP_FOR_SIMD_CLAUSE(nowait) OPENMP_FOR_SIMD_CLAUSE(safelen) +OPENMP_FOR_SIMD_CLAUSE(simdlen) OPENMP_FOR_SIMD_CLAUSE(linear) OPENMP_FOR_SIMD_CLAUSE(aligned) @@ -250,6 +253,7 @@ OPENMP_PARALLEL_FOR_SIMD_CLAUSE(lastprivate) OPENMP_PARALLEL_FOR_SIMD_CLAUSE(collapse) OPENMP_PARALLEL_FOR_SIMD_CLAUSE(schedule) OPENMP_PARALLEL_FOR_SIMD_CLAUSE(safelen) +OPENMP_PARALLEL_FOR_SIMD_CLAUSE(simdlen) OPENMP_PARALLEL_FOR_SIMD_CLAUSE(linear) OPENMP_PARALLEL_FOR_SIMD_CLAUSE(aligned) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index fd7df65cccc..40cccbcccfb 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -7893,6 +7893,10 @@ public: SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); + /// \brief Called on well-formed 'simdlen' clause. + OMPClause *ActOnOpenMPSimdlenClause(Expr *Length, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); /// \brief Called on well-formed 'collapse' clause. OMPClause *ActOnOpenMPCollapseClause(Expr *NumForLoops, SourceLocation StartLoc, diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index fb5fcc4902d..6f6c10daebf 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -623,6 +623,12 @@ void OMPClausePrinter::VisitOMPSafelenClause(OMPSafelenClause *Node) { OS << ")"; } +void OMPClausePrinter::VisitOMPSimdlenClause(OMPSimdlenClause *Node) { + OS << "simdlen("; + Node->getSimdlen()->printPretty(OS, nullptr, Policy, 0); + OS << ")"; +} + void OMPClausePrinter::VisitOMPCollapseClause(OMPCollapseClause *Node) { OS << "collapse("; Node->getNumForLoops()->printPretty(OS, nullptr, Policy, 0); diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 0318330abbd..2e5f2479aff 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -288,6 +288,11 @@ void OMPClauseProfiler::VisitOMPSafelenClause(const OMPSafelenClause *C) { Profiler->VisitStmt(C->getSafelen()); } +void OMPClauseProfiler::VisitOMPSimdlenClause(const OMPSimdlenClause *C) { + if (C->getSimdlen()) + Profiler->VisitStmt(C->getSimdlen()); +} + void OMPClauseProfiler::VisitOMPCollapseClause(const OMPCollapseClause *C) { if (C->getNumForLoops()) Profiler->VisitStmt(C->getNumForLoops()); diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 3262eec9c2c..e09c0a9e7f7 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -107,6 +107,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, case OMPC_final: case OMPC_num_threads: case OMPC_safelen: + case OMPC_simdlen: case OMPC_collapse: case OMPC_private: case OMPC_firstprivate: @@ -190,6 +191,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, case OMPC_final: case OMPC_num_threads: case OMPC_safelen: + case OMPC_simdlen: case OMPC_collapse: case OMPC_private: case OMPC_firstprivate: diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index ecf95c6d8ca..daa3dca7ce4 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -2050,6 +2050,7 @@ static void EmitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, case OMPC_lastprivate: case OMPC_reduction: case OMPC_safelen: + case OMPC_simdlen: case OMPC_collapse: case OMPC_default: case OMPC_seq_cst: diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index beb38e10f2a..ed71917dbcb 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -396,7 +396,8 @@ bool Parser::ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind, /// lastprivate-clause | reduction-clause | proc_bind-clause | /// schedule-clause | copyin-clause | copyprivate-clause | untied-clause | /// mergeable-clause | flush-clause | read-clause | write-clause | -/// update-clause | capture-clause | seq_cst-clause | device-clause +/// update-clause | capture-clause | seq_cst-clause | device-clause | +/// simdlen-clause /// OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, bool FirstClause) { @@ -414,6 +415,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_final: case OMPC_num_threads: case OMPC_safelen: + case OMPC_simdlen: case OMPC_collapse: case OMPC_ordered: case OMPC_device: @@ -422,6 +424,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, // At most one num_threads clause can appear on the directive. // OpenMP [2.8.1, simd construct, Restrictions] // Only one safelen clause can appear on a simd directive. + // Only one simdlen clause can appear on a simd directive. // Only one collapse clause can appear on a simd directive. // OpenMP [2.9.1, target data construct, Restrictions] // At most one device clause can appear on the directive. @@ -513,8 +516,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, } /// \brief Parsing of OpenMP clauses with single expressions like 'if', -/// 'final', 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams' or -/// 'thread_limit'. +/// 'final', 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams', +/// 'thread_limit' or 'simdlen'. /// /// if-clause: /// 'if' '(' expression ')' @@ -528,6 +531,9 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, /// safelen-clause: /// 'safelen' '(' expression ')' /// +/// simdlen-clause: +/// 'simdlen' '(' expression ')' +/// /// collapse-clause: /// 'collapse' '(' expression ')' /// diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 5d86cc23f00..77d8c2f662b 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -3535,6 +3535,30 @@ static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { return nullptr; } +static bool checkSimdlenSafelenValues(Sema &S, const Expr *Simdlen, + const Expr *Safelen) { + llvm::APSInt SimdlenRes, SafelenRes; + if (Simdlen->isValueDependent() || Simdlen->isTypeDependent() || + Simdlen->isInstantiationDependent() || + Simdlen->containsUnexpandedParameterPack()) + return false; + if (Safelen->isValueDependent() || Safelen->isTypeDependent() || + Safelen->isInstantiationDependent() || + Safelen->containsUnexpandedParameterPack()) + return false; + Simdlen->EvaluateAsInt(SimdlenRes, S.Context); + Safelen->EvaluateAsInt(SafelenRes, S.Context); + // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] + // If both simdlen and safelen clauses are specified, the value of the simdlen + // parameter must be less than or equal to the value of the safelen parameter. + if (SimdlenRes > SafelenRes) { + S.Diag(Simdlen->getExprLoc(), diag::err_omp_wrong_simdlen_safelen_values) + << Simdlen->getSourceRange() << Safelen->getSourceRange(); + return true; + } + return false; +} + StmtResult Sema::ActOnOpenMPSimdDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, @@ -3561,6 +3585,24 @@ StmtResult Sema::ActOnOpenMPSimdDirective( } } + // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] + // If both simdlen and safelen clauses are specified, the value of the simdlen + // parameter must be less than or equal to the value of the safelen parameter. + OMPSafelenClause *Safelen = nullptr; + OMPSimdlenClause *Simdlen = nullptr; + for (auto *Clause : Clauses) { + if (Clause->getClauseKind() == OMPC_safelen) + Safelen = cast<OMPSafelenClause>(Clause); + else if (Clause->getClauseKind() == OMPC_simdlen) + Simdlen = cast<OMPSimdlenClause>(Clause); + if (Safelen && Simdlen) + break; + } + if (Simdlen && Safelen && + checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(), + Safelen->getSafelen())) + return StmtError(); + getCurFunction()->setHasBranchProtectedScope(); return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); @@ -3624,6 +3666,24 @@ StmtResult Sema::ActOnOpenMPForSimdDirective( } } + // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] + // If both simdlen and safelen clauses are specified, the value of the simdlen + // parameter must be less than or equal to the value of the safelen parameter. + OMPSafelenClause *Safelen = nullptr; + OMPSimdlenClause *Simdlen = nullptr; + for (auto *Clause : Clauses) { + if (Clause->getClauseKind() == OMPC_safelen) + Safelen = cast<OMPSafelenClause>(Clause); + else if (Clause->getClauseKind() == OMPC_simdlen) + Simdlen = cast<OMPSimdlenClause>(Clause); + if (Safelen && Simdlen) + break; + } + if (Simdlen && Safelen && + checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(), + Safelen->getSafelen())) + return StmtError(); + getCurFunction()->setHasBranchProtectedScope(); return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); @@ -3796,6 +3856,24 @@ StmtResult Sema::ActOnOpenMPParallelForSimdDirective( } } + // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] + // If both simdlen and safelen clauses are specified, the value of the simdlen + // parameter must be less than or equal to the value of the safelen parameter. + OMPSafelenClause *Safelen = nullptr; + OMPSimdlenClause *Simdlen = nullptr; + for (auto *Clause : Clauses) { + if (Clause->getClauseKind() == OMPC_safelen) + Safelen = cast<OMPSafelenClause>(Clause); + else if (Clause->getClauseKind() == OMPC_simdlen) + Simdlen = cast<OMPSimdlenClause>(Clause); + if (Safelen && Simdlen) + break; + } + if (Simdlen && Safelen && + checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(), + Safelen->getSafelen())) + return StmtError(); + getCurFunction()->setHasBranchProtectedScope(); return OMPParallelForSimdDirective::Create( Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); @@ -4683,6 +4761,9 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, case OMPC_safelen: Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); break; + case OMPC_simdlen: + Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); + break; case OMPC_collapse: Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); break; @@ -4875,6 +4956,19 @@ OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); } +OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc) { + // OpenMP [2.8.1, simd construct, Description] + // The parameter of the simdlen clause must be a constant + // positive integer expression. + ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); + if (Simdlen.isInvalid()) + return nullptr; + return new (Context) + OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); +} + OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, SourceLocation StartLoc, SourceLocation LParenLoc, @@ -4932,6 +5026,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause( case OMPC_final: case OMPC_num_threads: case OMPC_safelen: + case OMPC_simdlen: case OMPC_collapse: case OMPC_schedule: case OMPC_private: @@ -5053,6 +5148,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( case OMPC_final: case OMPC_num_threads: case OMPC_safelen: + case OMPC_simdlen: case OMPC_collapse: case OMPC_default: case OMPC_proc_bind: @@ -5185,6 +5281,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, case OMPC_final: case OMPC_num_threads: case OMPC_safelen: + case OMPC_simdlen: case OMPC_collapse: case OMPC_schedule: case OMPC_private: @@ -5298,6 +5395,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause( case OMPC_final: case OMPC_num_threads: case OMPC_safelen: + case OMPC_simdlen: case OMPC_collapse: case OMPC_default: case OMPC_proc_bind: diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 7cc7b779724..7c2c2a587a6 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1395,6 +1395,16 @@ public: return getSema().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc, EndLoc); } + /// \brief Build a new OpenMP 'simdlen' clause. + /// + /// By default, performs semantic analysis to build the new OpenMP clause. + /// Subclasses may override this routine to provide different behavior. + OMPClause *RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc) { + return getSema().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc, EndLoc); + } + /// \brief Build a new OpenMP 'collapse' clause. /// /// By default, performs semantic analysis to build the new OpenMP clause. @@ -7221,6 +7231,16 @@ TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) { template <typename Derived> OMPClause * +TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) { + ExprResult E = getDerived().TransformExpr(C->getSimdlen()); + if (E.isInvalid()) + return nullptr; + return getDerived().RebuildOMPSimdlenClause( + E.get(), C->getLocStart(), C->getLParenLoc(), C->getLocEnd()); +} + +template <typename Derived> +OMPClause * TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) { ExprResult E = getDerived().TransformExpr(C->getNumForLoops()); if (E.isInvalid()) diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 18b1051d177..4a76ca0bc7d 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -1716,6 +1716,9 @@ OMPClause *OMPClauseReader::readClause() { case OMPC_safelen: C = new (Context) OMPSafelenClause(); break; + case OMPC_simdlen: + C = new (Context) OMPSimdlenClause(); + break; case OMPC_collapse: C = new (Context) OMPCollapseClause(); break; @@ -1819,6 +1822,11 @@ void OMPClauseReader::VisitOMPSafelenClause(OMPSafelenClause *C) { C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx)); } +void OMPClauseReader::VisitOMPSimdlenClause(OMPSimdlenClause *C) { + C->setSimdlen(Reader->Reader.ReadSubExpr()); + C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx)); +} + void OMPClauseReader::VisitOMPCollapseClause(OMPCollapseClause *C) { C->setNumForLoops(Reader->Reader.ReadSubExpr()); C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx)); diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index c91db223d96..6bf5b7d3057 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -1737,6 +1737,11 @@ void OMPClauseWriter::VisitOMPSafelenClause(OMPSafelenClause *C) { Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record); } +void OMPClauseWriter::VisitOMPSimdlenClause(OMPSimdlenClause *C) { + Writer->Writer.AddStmt(C->getSimdlen()); + Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record); +} + void OMPClauseWriter::VisitOMPCollapseClause(OMPCollapseClause *C) { Writer->Writer.AddStmt(C->getNumForLoops()); Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record); diff --git a/clang/test/OpenMP/for_simd_ast_print.cpp b/clang/test/OpenMP/for_simd_ast_print.cpp index 21c15a2fd67..725c727e261 100644 --- a/clang/test/OpenMP/for_simd_ast_print.cpp +++ b/clang/test/OpenMP/for_simd_ast_print.cpp @@ -35,8 +35,8 @@ template<class T> struct S { // CHECK: T res; // CHECK: T val; // CHECK: T lin = 0; - #pragma omp for simd private(val) safelen(7) linear(lin : -5) lastprivate(res) -// CHECK-NEXT: #pragma omp for simd private(val) safelen(7) linear(lin: -5) lastprivate(res) + #pragma omp for simd private(val) safelen(7) linear(lin : -5) lastprivate(res) simdlen(5) +// CHECK-NEXT: #pragma omp for simd private(val) safelen(7) linear(lin: -5) lastprivate(res) simdlen(5) for (T i = 7; i < m_a; ++i) { val = v[i-7] + m_a; res = val; @@ -44,8 +44,8 @@ template<class T> struct S { } const T clen = 3; // CHECK: T clen = 3; - #pragma omp for simd safelen(clen-1) -// CHECK-NEXT: #pragma omp for simd safelen(clen - 1) + #pragma omp for simd safelen(clen-1) simdlen(clen-1) +// CHECK-NEXT: #pragma omp for simd safelen(clen - 1) simdlen(clen - 1) for(T i = clen+2; i < 20; ++i) { // CHECK-NEXT: for (T i = clen + 2; i < 20; ++i) { v[i] = v[v-clen] + 1; @@ -62,7 +62,7 @@ template<class T> struct S { template<int LEN> struct S2 { static void func(int n, float *a, float *b, float *c) { int k1 = 0, k2 = 0; -#pragma omp for simd safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN) +#pragma omp for simd safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN) simdlen(LEN) for(int i = 0; i < n; i++) { c[i] = a[i] + b[i]; c[k1] = a[k1] + b[k1]; @@ -77,7 +77,7 @@ template<int LEN> struct S2 { // CHECK: template <int LEN = 4> struct S2 { // CHECK-NEXT: static void func(int n, float *a, float *b, float *c) { // CHECK-NEXT: int k1 = 0, k2 = 0; -// CHECK-NEXT: #pragma omp for simd safelen(4) linear(k1,k2: 4) aligned(a: 4) +// CHECK-NEXT: #pragma omp for simd safelen(4) linear(k1,k2: 4) aligned(a: 4) simdlen(4) // CHECK-NEXT: for (int i = 0; i < n; i++) { // CHECK-NEXT: c[i] = a[i] + b[i]; // CHECK-NEXT: c[k1] = a[k1] + b[k1]; @@ -114,8 +114,8 @@ int main (int argc, char **argv) { // CHECK-NEXT: foo(); const int CLEN = 4; // CHECK-NEXT: const int CLEN = 4; - #pragma omp for simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 ) -// CHECK-NEXT: #pragma omp for simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1) + #pragma omp for simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 ) simdlen(CLEN) +// CHECK-NEXT: #pragma omp for simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1) simdlen(CLEN) for (int i = 0; i < 10; ++i)foo(); // CHECK-NEXT: for (int i = 0; i < 10; ++i) // CHECK-NEXT: foo(); diff --git a/clang/test/OpenMP/for_simd_misc_messages.c b/clang/test/OpenMP/for_simd_misc_messages.c index e87a78976e2..77af54dde7f 100644 --- a/clang/test/OpenMP/for_simd_misc_messages.c +++ b/clang/test/OpenMP/for_simd_misc_messages.c @@ -167,6 +167,103 @@ void test_safelen() { ; } +void test_simdlen() { + int i; +// expected-error@+1 {{expected '('}} +#pragma omp for simd simdlen + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp for simd simdlen( + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp for simd simdlen() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp for simd simdlen(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp for simd simdlen(, ) + for (i = 0; i < 16; ++i) + ; +// expected-warning@+2 {{extra tokens at the end of '#pragma omp for simd' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp for simd simdlen 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp for simd simdlen(4 + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp for simd simdlen(4, + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp for simd simdlen(4, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp for simd simdlen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp for simd simdlen(4 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp for simd simdlen(4, , 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp for simd simdlen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp for simd simdlen(4, 8) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp for simd simdlen(2.5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp for simd simdlen(foo()) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'simdlen' clause must be a positive integer value}} +#pragma omp for simd simdlen(-5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'simdlen' clause must be a positive integer value}} +#pragma omp for simd simdlen(0) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'simdlen' clause must be a positive integer value}} +#pragma omp for simd simdlen(5 - 5) + for (i = 0; i < 16; ++i) + ; +} + +void test_safelen_simdlen() { + int i; +// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}} +#pragma omp for simd simdlen(6) safelen(5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}} +#pragma omp for simd safelen(5) simdlen(6) + for (i = 0; i < 16; ++i) + ; +} + void test_collapse() { int i; #pragma omp parallel diff --git a/clang/test/OpenMP/for_simd_simdlen_messages.cpp b/clang/test/OpenMP/for_simd_simdlen_messages.cpp new file mode 100644 index 00000000000..f705e22672b --- /dev/null +++ b/clang/test/OpenMP/for_simd_simdlen_messages.cpp @@ -0,0 +1,79 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} + #pragma omp for simd simdlen // expected-error {{expected '(' after 'simdlen'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd simdlen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd simdlen () // expected-error {{expected expression}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} + // expected-error@+2 2 {{expression is not an integral constant expression}} + // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} + #pragma omp for simd simdlen (argc + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 {{argument to 'simdlen' clause must be a positive integer value}} + #pragma omp for simd simdlen (ST // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd simdlen (1)) // expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd simdlen ((ST > 0) ? 1 + ST : 2) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+3 2 {{directive '#pragma omp for simd' cannot contain more than one 'simdlen' clause}} + // expected-error@+2 2 {{argument to 'simdlen' clause must be a positive integer value}} + // expected-error@+1 2 {{expression is not an integral constant expression}} + #pragma omp for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd simdlen (S) // expected-error {{'S' does not refer to a value}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 2 {{expression is not an integral constant expression}} + #pragma omp for simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd simdlen (4) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp for simd simdlen (N) // expected-error {{argument to 'simdlen' clause must be a positive integer value}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + return argc; +} + +int main(int argc, char **argv) { + #pragma omp for simd simdlen // expected-error {{expected '(' after 'simdlen'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd simdlen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd simdlen () // expected-error {{expected expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd simdlen (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd simdlen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd simdlen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+3 {{expression is not an integral constant expression}} + // expected-error@+2 2 {{directive '#pragma omp for simd' cannot contain more than one 'simdlen' clause}} + // expected-error@+1 2 {{argument to 'simdlen' clause must be a positive integer value}} + #pragma omp for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp for simd simdlen (S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+1 {{expression is not an integral constant expression}} + #pragma omp for simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+3 {{statement after '#pragma omp for simd' must be a for loop}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} + #pragma omp for simd simdlen(simdlen(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 12, 4>' requested here}} + return tmain<int, char, 12, 4>(argc, argv); +} + diff --git a/clang/test/OpenMP/parallel_for_simd_ast_print.cpp b/clang/test/OpenMP/parallel_for_simd_ast_print.cpp index cd62fc51af7..ef0c002f21e 100644 --- a/clang/test/OpenMP/parallel_for_simd_ast_print.cpp +++ b/clang/test/OpenMP/parallel_for_simd_ast_print.cpp @@ -35,8 +35,8 @@ template<class T> struct S { // CHECK: T res; // CHECK: T val; // CHECK: T lin = 0; - #pragma omp parallel for simd private(val) safelen(7) linear(lin : -5) lastprivate(res) -// CHECK-NEXT: #pragma omp parallel for simd private(val) safelen(7) linear(lin: -5) lastprivate(res) + #pragma omp parallel for simd private(val) safelen(7) linear(lin : -5) lastprivate(res) simdlen(5) +// CHECK-NEXT: #pragma omp parallel for simd private(val) safelen(7) linear(lin: -5) lastprivate(res) simdlen(5) for (T i = 7; i < m_a; ++i) { val = v[i-7] + m_a; res = val; @@ -44,8 +44,8 @@ template<class T> struct S { } const T clen = 3; // CHECK: T clen = 3; - #pragma omp parallel for simd safelen(clen-1) -// CHECK-NEXT: #pragma omp parallel for simd safelen(clen - 1) + #pragma omp parallel for simd safelen(clen-1) simdlen(clen-1) +// CHECK-NEXT: #pragma omp parallel for simd safelen(clen - 1) simdlen(clen - 1) for(T i = clen+2; i < 20; ++i) { // CHECK-NEXT: for (T i = clen + 2; i < 20; ++i) { v[i] = v[v-clen] + 1; @@ -62,7 +62,7 @@ template<class T> struct S { template<int LEN> struct S2 { static void func(int n, float *a, float *b, float *c) { int k1 = 0, k2 = 0; -#pragma omp parallel for simd safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN) +#pragma omp parallel for simd safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN) simdlen(LEN) for(int i = 0; i < n; i++) { c[i] = a[i] + b[i]; c[k1] = a[k1] + b[k1]; @@ -77,7 +77,7 @@ template<int LEN> struct S2 { // CHECK: template <int LEN = 4> struct S2 { // CHECK-NEXT: static void func(int n, float *a, float *b, float *c) { // CHECK-NEXT: int k1 = 0, k2 = 0; -// CHECK-NEXT: #pragma omp parallel for simd safelen(4) linear(k1,k2: 4) aligned(a: 4) +// CHECK-NEXT: #pragma omp parallel for simd safelen(4) linear(k1,k2: 4) aligned(a: 4) simdlen(4) // CHECK-NEXT: for (int i = 0; i < n; i++) { // CHECK-NEXT: c[i] = a[i] + b[i]; // CHECK-NEXT: c[k1] = a[k1] + b[k1]; @@ -114,8 +114,8 @@ int main (int argc, char **argv) { // CHECK-NEXT: foo(); const int CLEN = 4; // CHECK-NEXT: const int CLEN = 4; - #pragma omp parallel for simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 ) -// CHECK-NEXT: #pragma omp parallel for simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1) + #pragma omp parallel for simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 ) simdlen(CLEN) +// CHECK-NEXT: #pragma omp parallel for simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1) simdlen(CLEN) for (int i = 0; i < 10; ++i)foo(); // CHECK-NEXT: for (int i = 0; i < 10; ++i) // CHECK-NEXT: foo(); diff --git a/clang/test/OpenMP/parallel_for_simd_misc_messages.c b/clang/test/OpenMP/parallel_for_simd_misc_messages.c index ed9ac4b5242..0f0d76b0711 100644 --- a/clang/test/OpenMP/parallel_for_simd_misc_messages.c +++ b/clang/test/OpenMP/parallel_for_simd_misc_messages.c @@ -167,6 +167,103 @@ void test_safelen() { ; } +void test_simdlen() { + int i; +// expected-error@+1 {{expected '('}} +#pragma omp parallel for simd simdlen + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd simdlen( + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp parallel for simd simdlen() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd simdlen(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd simdlen(, ) + for (i = 0; i < 16; ++i) + ; +// expected-warning@+2 {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp parallel for simd simdlen 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd simdlen(4 + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd simdlen(4, + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd simdlen(4, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel for simd simdlen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd simdlen(4 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd simdlen(4, , 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp parallel for simd simdlen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp parallel for simd simdlen(4, 8) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp parallel for simd simdlen(2.5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp parallel for simd simdlen(foo()) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'simdlen' clause must be a positive integer value}} +#pragma omp parallel for simd simdlen(-5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'simdlen' clause must be a positive integer value}} +#pragma omp parallel for simd simdlen(0) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'simdlen' clause must be a positive integer value}} +#pragma omp parallel for simd simdlen(5 - 5) + for (i = 0; i < 16; ++i) + ; +} + +void test_safelen_simdlen() { + int i; +// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}} +#pragma omp parallel for simd simdlen(6) safelen(5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}} +#pragma omp parallel for simd safelen(5) simdlen(6) + for (i = 0; i < 16; ++i) + ; +} + void test_collapse() { int i; #pragma omp parallel diff --git a/clang/test/OpenMP/parallel_for_simd_simdlen_messages.cpp b/clang/test/OpenMP/parallel_for_simd_simdlen_messages.cpp new file mode 100644 index 00000000000..b71c210d677 --- /dev/null +++ b/clang/test/OpenMP/parallel_for_simd_simdlen_messages.cpp @@ -0,0 +1,79 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} + #pragma omp parallel for simd simdlen // expected-error {{expected '(' after 'simdlen'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd simdlen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd simdlen () // expected-error {{expected expression}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} + // expected-error@+2 2 {{expression is not an integral constant expression}} + // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} + #pragma omp parallel for simd simdlen (argc + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 {{argument to 'simdlen' clause must be a positive integer value}} + #pragma omp parallel for simd simdlen (ST // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd simdlen (1)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd simdlen ((ST > 0) ? 1 + ST : 2) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+3 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'simdlen' clause}} + // expected-error@+2 2 {{argument to 'simdlen' clause must be a positive integer value}} + // expected-error@+1 2 {{expression is not an integral constant expression}} + #pragma omp parallel for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd simdlen (S) // expected-error {{'S' does not refer to a value}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 2 {{expression is not an integral constant expression}} + #pragma omp parallel for simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd simdlen (4) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for simd simdlen (N) // expected-error {{argument to 'simdlen' clause must be a positive integer value}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + return argc; +} + +int main(int argc, char **argv) { + #pragma omp parallel for simd simdlen // expected-error {{expected '(' after 'simdlen'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd simdlen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd simdlen () // expected-error {{expected expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd simdlen (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd simdlen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd simdlen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+3 {{expression is not an integral constant expression}} + // expected-error@+2 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'simdlen' clause}} + // expected-error@+1 2 {{argument to 'simdlen' clause must be a positive integer value}} + #pragma omp parallel for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp parallel for simd simdlen (S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+1 {{expression is not an integral constant expression}} + #pragma omp parallel for simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+3 {{statement after '#pragma omp parallel for simd' must be a for loop}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} + #pragma omp parallel for simd simdlen(simdlen(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 12, 4>' requested here}} + return tmain<int, char, 12, 4>(argc, argv); +} + diff --git a/clang/test/OpenMP/simd_ast_print.cpp b/clang/test/OpenMP/simd_ast_print.cpp index 069862b6dfb..59dade4990d 100644 --- a/clang/test/OpenMP/simd_ast_print.cpp +++ b/clang/test/OpenMP/simd_ast_print.cpp @@ -35,8 +35,8 @@ template<class T> struct S { // CHECK: T res; // CHECK: T val; // CHECK: T lin = 0; - #pragma omp simd private(val) safelen(7) linear(lin : -5) lastprivate(res) -// CHECK-NEXT: #pragma omp simd private(val) safelen(7) linear(lin: -5) lastprivate(res) + #pragma omp simd private(val) safelen(7) linear(lin : -5) lastprivate(res) simdlen(5) +// CHECK-NEXT: #pragma omp simd private(val) safelen(7) linear(lin: -5) lastprivate(res) simdlen(5) for (T i = 7; i < m_a; ++i) { val = v[i-7] + m_a; res = val; @@ -44,8 +44,8 @@ template<class T> struct S { } const T clen = 3; // CHECK: T clen = 3; - #pragma omp simd safelen(clen-1) -// CHECK-NEXT: #pragma omp simd safelen(clen - 1) + #pragma omp simd safelen(clen-1) simdlen(clen-1) +// CHECK-NEXT: #pragma omp simd safelen(clen - 1) simdlen(clen - 1) for(T i = clen+2; i < 20; ++i) { // CHECK-NEXT: for (T i = clen + 2; i < 20; ++i) { v[i] = v[v-clen] + 1; @@ -62,7 +62,7 @@ template<class T> struct S { template<int LEN> struct S2 { static void func(int n, float *a, float *b, float *c) { int k1 = 0, k2 = 0; -#pragma omp simd safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN) +#pragma omp simd safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN) simdlen(LEN) for(int i = 0; i < n; i++) { c[i] = a[i] + b[i]; c[k1] = a[k1] + b[k1]; @@ -77,7 +77,7 @@ template<int LEN> struct S2 { // CHECK: template <int LEN = 4> struct S2 { // CHECK-NEXT: static void func(int n, float *a, float *b, float *c) { // CHECK-NEXT: int k1 = 0, k2 = 0; -// CHECK-NEXT: #pragma omp simd safelen(4) linear(k1,k2: 4) aligned(a: 4) +// CHECK-NEXT: #pragma omp simd safelen(4) linear(k1,k2: 4) aligned(a: 4) simdlen(4) // CHECK-NEXT: for (int i = 0; i < n; i++) { // CHECK-NEXT: c[i] = a[i] + b[i]; // CHECK-NEXT: c[k1] = a[k1] + b[k1]; @@ -112,8 +112,8 @@ int main (int argc, char **argv) { // CHECK-NEXT: foo(); const int CLEN = 4; // CHECK-NEXT: const int CLEN = 4; - #pragma omp simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 ) -// CHECK-NEXT: #pragma omp simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1) + #pragma omp simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 ) simdlen(CLEN) +// CHECK-NEXT: #pragma omp simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1) simdlen(CLEN) for (int i = 0; i < 10; ++i)foo(); // CHECK-NEXT: for (int i = 0; i < 10; ++i) // CHECK-NEXT: foo(); diff --git a/clang/test/OpenMP/simd_misc_messages.c b/clang/test/OpenMP/simd_misc_messages.c index 2c0c08e68e0..bf03aa8a7ed 100644 --- a/clang/test/OpenMP/simd_misc_messages.c +++ b/clang/test/OpenMP/simd_misc_messages.c @@ -166,6 +166,103 @@ void test_safelen() { ; } +void test_simdlen() { + int i; +// expected-error@+1 {{expected '('}} +#pragma omp simd simdlen + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp simd simdlen( + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp simd simdlen() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp simd simdlen(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp simd simdlen(, ) + for (i = 0; i < 16; ++i) + ; +// expected-warning@+2 {{extra tokens at the end of '#pragma omp simd' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp simd simdlen 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp simd simdlen(4 + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp simd simdlen(4, + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp simd simdlen(4, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp simd simdlen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp simd simdlen(4 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp simd simdlen(4, , 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp simd simdlen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp simd simdlen(4, 8) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp simd simdlen(2.5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp simd simdlen(foo()) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'simdlen' clause must be a positive integer value}} +#pragma omp simd simdlen(-5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'simdlen' clause must be a positive integer value}} +#pragma omp simd simdlen(0) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'simdlen' clause must be a positive integer value}} +#pragma omp simd simdlen(5 - 5) + for (i = 0; i < 16; ++i) + ; +} + +void test_safelen_simdlen() { + int i; +// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}} +#pragma omp simd simdlen(6) safelen(5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}} +#pragma omp simd safelen(5) simdlen(6) + for (i = 0; i < 16; ++i) + ; +} + void test_collapse() { int i; // expected-error@+1 {{expected '('}} diff --git a/clang/test/OpenMP/simd_simdlen_messages.cpp b/clang/test/OpenMP/simd_simdlen_messages.cpp new file mode 100644 index 00000000000..b9b00041f60 --- /dev/null +++ b/clang/test/OpenMP/simd_simdlen_messages.cpp @@ -0,0 +1,79 @@ +// RUN: %clang_cc1 -verify -fopenmp %s + +void foo() { +} + +bool foobool(int argc) { + return argc; +} + +struct S1; // expected-note {{declared here}} + +template <class T, typename S, int N, int ST> // expected-note {{declared here}} +T tmain(T argc, S **argv) { //expected-note 2 {{declared here}} + #pragma omp simd simdlen // expected-error {{expected '(' after 'simdlen'}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp simd simdlen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp simd simdlen () // expected-error {{expected expression}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} + // expected-error@+2 2 {{expression is not an integral constant expression}} + // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}} + #pragma omp simd simdlen (argc + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 {{argument to 'simdlen' clause must be a positive integer value}} + #pragma omp simd simdlen (ST // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp simd simdlen (1)) // expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp simd simdlen ((ST > 0) ? 1 + ST : 2) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+3 2 {{directive '#pragma omp simd' cannot contain more than one 'simdlen' clause}} + // expected-error@+2 2 {{argument to 'simdlen' clause must be a positive integer value}} + // expected-error@+1 2 {{expression is not an integral constant expression}} + #pragma omp simd simdlen (foobool(argc)), simdlen (true), simdlen (-5) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp simd simdlen (S) // expected-error {{'S' does not refer to a value}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + // expected-error@+1 2 {{expression is not an integral constant expression}} + #pragma omp simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp simd simdlen (4) + for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp simd simdlen (N) // expected-error {{argument to 'simdlen' clause must be a positive integer value}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + return argc; +} + +int main(int argc, char **argv) { + #pragma omp simd simdlen // expected-error {{expected '(' after 'simdlen'}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp simd simdlen ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp simd simdlen () // expected-error {{expected expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp simd simdlen (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp simd simdlen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp simd simdlen (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+3 {{expression is not an integral constant expression}} + // expected-error@+2 2 {{directive '#pragma omp simd' cannot contain more than one 'simdlen' clause}} + // expected-error@+1 2 {{argument to 'simdlen' clause must be a positive integer value}} + #pragma omp simd simdlen (foobool(argc)), simdlen (true), simdlen (-5) + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + #pragma omp simd simdlen (S1) // expected-error {{'S1' does not refer to a value}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+1 {{expression is not an integral constant expression}} + #pragma omp simd simdlen (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; + // expected-error@+3 {{statement after '#pragma omp simd' must be a for loop}} + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}} + #pragma omp simd simdlen(simdlen(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + foo(); + // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 12, 4>' requested here}} + return tmain<int, char, 12, 4>(argc, argv); +} + diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index e5e2730e68f..347b377e23c 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -2019,6 +2019,10 @@ void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) { Visitor->AddStmt(C->getSafelen()); } +void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) { + Visitor->AddStmt(C->getSimdlen()); +} + void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) { Visitor->AddStmt(C->getNumForLoops()); } |

