diff options
Diffstat (limited to 'clang')
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()); } |

