diff options
-rw-r--r-- | clang/include/clang/AST/StmtOpenMP.h | 29 | ||||
-rw-r--r-- | clang/lib/AST/StmtOpenMP.cpp | 9 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGStmtOpenMP.cpp | 24 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 466 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderStmt.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterStmt.cpp | 1 | ||||
-rw-r--r-- | clang/test/OpenMP/distribute_codegen.cpp | 6 | ||||
-rw-r--r-- | clang/test/OpenMP/for_codegen.cpp | 3 | ||||
-rw-r--r-- | clang/test/OpenMP/for_loop_messages.cpp | 6 | ||||
-rw-r--r-- | clang/test/OpenMP/for_simd_loop_messages.cpp | 6 | ||||
-rw-r--r-- | clang/test/OpenMP/parallel_for_loop_messages.cpp | 6 | ||||
-rw-r--r-- | clang/test/OpenMP/parallel_for_simd_loop_messages.cpp | 6 | ||||
-rw-r--r-- | clang/test/OpenMP/simd_codegen.cpp | 2 | ||||
-rw-r--r-- | clang/test/OpenMP/target_parallel_for_loop_messages.cpp | 6 | ||||
-rw-r--r-- | clang/test/OpenMP/taskloop_loop_messages.cpp | 6 | ||||
-rw-r--r-- | clang/test/OpenMP/taskloop_simd_loop_messages.cpp | 6 |
16 files changed, 267 insertions, 316 deletions
diff --git a/clang/include/clang/AST/StmtOpenMP.h b/clang/include/clang/AST/StmtOpenMP.h index 307ceb87937..407bf76400f 100644 --- a/clang/include/clang/AST/StmtOpenMP.h +++ b/clang/include/clang/AST/StmtOpenMP.h @@ -312,21 +312,22 @@ class OMPLoopDirective : public OMPExecutableDirective { CondOffset = 5, InitOffset = 6, IncOffset = 7, + PreInitsOffset = 8, // The '...End' enumerators do not correspond to child expressions - they // specify the offset to the end (and start of the following counters/ // updates/finals arrays). - DefaultEnd = 8, + DefaultEnd = 9, // The following 7 exprs are used by worksharing loops only. - IsLastIterVariableOffset = 8, - LowerBoundVariableOffset = 9, - UpperBoundVariableOffset = 10, - StrideVariableOffset = 11, - EnsureUpperBoundOffset = 12, - NextLowerBoundOffset = 13, - NextUpperBoundOffset = 14, + IsLastIterVariableOffset = 9, + LowerBoundVariableOffset = 10, + UpperBoundVariableOffset = 11, + StrideVariableOffset = 12, + EnsureUpperBoundOffset = 13, + NextLowerBoundOffset = 14, + NextUpperBoundOffset = 15, // Offset to the end (and start of the following counters/updates/finals // arrays) for worksharing loop directives. - WorksharingEnd = 15, + WorksharingEnd = 16, }; /// \brief Get the counters storage. @@ -422,6 +423,9 @@ protected: } void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; } void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; } + void setPreInits(Stmt *PreInits) { + *std::next(child_begin(), PreInitsOffset) = PreInits; + } void setIsLastIterVariable(Expr *IL) { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || isOpenMPTaskLoopDirective(getDirectiveKind()) || @@ -521,6 +525,8 @@ public: SmallVector<Expr *, 4> Updates; /// \brief Final loop counter values for GodeGen. SmallVector<Expr *, 4> Finals; + /// Init statement for all captured expressions. + Stmt *PreInits; /// \brief Check if all the expressions are built (does not check the /// worksharing ones). @@ -559,6 +565,7 @@ public: Updates[i] = nullptr; Finals[i] = nullptr; } + PreInits = nullptr; } }; @@ -593,6 +600,10 @@ public: return const_cast<Expr *>( reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset))); } + const Stmt *getPreInits() const { + return *std::next(child_begin(), PreInitsOffset); + } + Stmt *getPreInits() { return *std::next(child_begin(), PreInitsOffset); } Expr *getIsLastIterVariable() const { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || isOpenMPTaskLoopDirective(getDirectiveKind()) || diff --git a/clang/lib/AST/StmtOpenMP.cpp b/clang/lib/AST/StmtOpenMP.cpp index 49fe88eeddf..f3291a5113c 100644 --- a/clang/lib/AST/StmtOpenMP.cpp +++ b/clang/lib/AST/StmtOpenMP.cpp @@ -105,6 +105,7 @@ OMPSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc, Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setPreInits(Exprs.PreInits); return Dir; } @@ -153,6 +154,7 @@ OMPForDirective::Create(const ASTContext &C, SourceLocation StartLoc, Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setPreInits(Exprs.PreInits); Dir->setHasCancel(HasCancel); return Dir; } @@ -202,6 +204,7 @@ OMPForSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc, Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setPreInits(Exprs.PreInits); return Dir; } @@ -367,6 +370,7 @@ OMPParallelForDirective *OMPParallelForDirective::Create( Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setPreInits(Exprs.PreInits); Dir->setHasCancel(HasCancel); return Dir; } @@ -414,6 +418,7 @@ OMPParallelForSimdDirective *OMPParallelForSimdDirective::Create( Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setPreInits(Exprs.PreInits); return Dir; } @@ -750,6 +755,7 @@ OMPTargetParallelForDirective *OMPTargetParallelForDirective::Create( Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setPreInits(Exprs.PreInits); Dir->setHasCancel(HasCancel); return Dir; } @@ -889,6 +895,7 @@ OMPTaskLoopDirective *OMPTaskLoopDirective::Create( Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setPreInits(Exprs.PreInits); return Dir; } @@ -936,6 +943,7 @@ OMPTaskLoopSimdDirective *OMPTaskLoopSimdDirective::Create( Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setPreInits(Exprs.PreInits); return Dir; } @@ -982,6 +990,7 @@ OMPDistributeDirective *OMPDistributeDirective::Create( Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setPreInits(Exprs.PreInits); return Dir; } diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 87c9b3b4d1d..84059ab2912 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -52,6 +52,25 @@ public: } }; +/// Private scope for OpenMP loop-based directives, that supports capturing +/// of used expression from loop statement. +class OMPLoopScope : public CodeGenFunction::RunCleanupsScope { + void emitPreInitStmt(CodeGenFunction &CGF, const OMPLoopDirective &S) { + if (auto *LD = dyn_cast<OMPLoopDirective>(&S)) { + if (auto *PreInits = cast_or_null<DeclStmt>(LD->getPreInits())) { + for (const auto *I : PreInits->decls()) + CGF.EmitVarDecl(cast<VarDecl>(*I)); + } + } + } + +public: + OMPLoopScope(CodeGenFunction &CGF, const OMPLoopDirective &S) + : CodeGenFunction::RunCleanupsScope(CGF) { + emitPreInitStmt(CGF, S); + } +}; + } // namespace llvm::Value *CodeGenFunction::getTypeSize(QualType Ty) { @@ -1467,6 +1486,7 @@ void CodeGenFunction::EmitOMPSimdFinal( void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { + OMPLoopScope PreInitScope(CGF, S); // if (PreCond) { // for (IV in 0..LastIteration) BODY; // <Final counter/linear vars updates>; @@ -1781,6 +1801,7 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) { bool HasLastprivateClause; // Check pre-condition. { + OMPLoopScope PreInitScope(*this, S); // Skip the entire loop if we don't meet the precondition. // If the condition constant folds and can be elided, avoid emitting the // whole loop. @@ -2397,6 +2418,7 @@ void CodeGenFunction::EmitOMPDistributeLoop(const OMPDistributeDirective &S) { // Check pre-condition. { + OMPLoopScope PreInitScope(*this, S); // Skip the entire loop if we don't meet the precondition. // If the condition constant folds and can be elided, avoid emitting the // whole loop. @@ -3174,6 +3196,7 @@ void CodeGenFunction::EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S) { OMPLexicalScope Scope(*this, S); CGM.getOpenMPRuntime().emitInlinedDirective( *this, OMPD_taskloop, [&S](CodeGenFunction &CGF, PrePostActionTy &) { + OMPLoopScope PreInitScope(CGF, S); CGF.EmitStmt( cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); }); @@ -3185,6 +3208,7 @@ void CodeGenFunction::EmitOMPTaskLoopSimdDirective( OMPLexicalScope Scope(*this, S); CGM.getOpenMPRuntime().emitInlinedDirective( *this, OMPD_taskloop_simd, [&S](CodeGenFunction &CGF, PrePostActionTy &) { + OMPLoopScope PreInitScope(CGF, S); CGF.EmitStmt( cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); }); diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index d58f91104fe..c1233d8278f 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -1028,9 +1028,9 @@ void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { PopExpressionEvaluationContext(); } -static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, - Expr *NumIterations, Sema &SemaRef, - Scope *S); +static bool +FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, + Expr *NumIterations, Sema &SemaRef, Scope *S); namespace { @@ -1708,10 +1708,11 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { } static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, - Expr *CaptureExpr, bool WithInit) { + Expr *CaptureExpr, bool WithInit, + bool AsExpression) { assert(CaptureExpr); ASTContext &C = S.getASTContext(); - Expr *Init = CaptureExpr->IgnoreImpCasts(); + Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); QualType Ty = Init->getType(); if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { if (S.getLangOpts().CPlusPlus) @@ -1741,17 +1742,28 @@ static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, if (auto *VD = S.IsOpenMPCapturedDecl(D)) CD = cast<OMPCapturedExprDecl>(VD); else - CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit); + CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, + /*AsExpression=*/false); return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), SourceLocation()); } -static DeclRefExpr *buildCapture(Sema &S, Expr *CaptureExpr) { - auto *CD = - buildCaptureDecl(S, &S.getASTContext().Idents.get(".capture_expr."), - CaptureExpr, /*WithInit=*/true); - return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), - SourceLocation()); +static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { + if (!Ref) { + auto *CD = + buildCaptureDecl(S, &S.getASTContext().Idents.get(".capture_expr."), + CaptureExpr, /*WithInit=*/true, /*AsExpression=*/true); + Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), + CaptureExpr->getExprLoc()); + } + ExprResult Res = Ref; + if (!S.getLangOpts().CPlusPlus && + CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && + Ref->getType()->isPointerType()) + Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); + if (!Res.isUsable()) + return ExprError(); + return CaptureExpr->isGLValue() ? Res : S.DefaultLvalueConversion(Res.get()); } StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, @@ -3251,9 +3263,12 @@ public: /// \brief True if the step should be subtracted. bool ShouldSubtractStep() const { return SubtractStep; } /// \brief Build the expression to calculate the number of iterations. - Expr *BuildNumIterations(Scope *S, const bool LimitedType) const; + Expr * + BuildNumIterations(Scope *S, const bool LimitedType, + llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; /// \brief Build the precondition expression for the loops. - Expr *BuildPreCond(Scope *S, Expr *Cond) const; + Expr *BuildPreCond(Scope *S, Expr *Cond, + llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; /// \brief Build reference expression to the counter be used for codegen. Expr *BuildCounterVar() const; /// \brief Build reference expression to the private counter be used for @@ -3613,62 +3628,26 @@ bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) { return true; } -namespace { -// Transform variables declared in GNU statement expressions to new ones to -// avoid crash on codegen. -class TransformToNewDefs : public TreeTransform<TransformToNewDefs> { - typedef TreeTransform<TransformToNewDefs> BaseTransform; - -public: - TransformToNewDefs(Sema &SemaRef) : BaseTransform(SemaRef) {} - - Decl *TransformDefinition(SourceLocation Loc, Decl *D) { - if (auto *VD = cast<VarDecl>(D)) - if (!isa<ParmVarDecl>(D) && !isa<VarTemplateSpecializationDecl>(D) && - !isa<ImplicitParamDecl>(D)) { - auto *NewVD = VarDecl::Create( - SemaRef.Context, VD->getDeclContext(), VD->getLocStart(), - VD->getLocation(), VD->getIdentifier(), VD->getType(), - VD->getTypeSourceInfo(), VD->getStorageClass()); - NewVD->setTSCSpec(VD->getTSCSpec()); - NewVD->setInit(VD->getInit()); - NewVD->setInitStyle(VD->getInitStyle()); - NewVD->setExceptionVariable(VD->isExceptionVariable()); - NewVD->setNRVOVariable(VD->isNRVOVariable()); - NewVD->setCXXForRangeDecl(VD->isCXXForRangeDecl()); - NewVD->setConstexpr(VD->isConstexpr()); - NewVD->setInitCapture(VD->isInitCapture()); - NewVD->setPreviousDeclInSameBlockScope( - VD->isPreviousDeclInSameBlockScope()); - VD->getDeclContext()->addHiddenDecl(NewVD); - if (VD->hasAttrs()) - NewVD->setAttrs(VD->getAttrs()); - transformedLocalDecl(VD, NewVD); - return NewVD; - } - return BaseTransform::TransformDefinition(Loc, D); - } - - ExprResult TransformDeclRefExpr(DeclRefExpr *E) { - if (auto *NewD = TransformDecl(E->getExprLoc(), E->getDecl())) - if (E->getDecl() != NewD) { - NewD->setReferenced(); - NewD->markUsed(SemaRef.Context); - return DeclRefExpr::Create( - SemaRef.Context, E->getQualifierLoc(), E->getTemplateKeywordLoc(), - cast<ValueDecl>(NewD), E->refersToEnclosingVariableOrCapture(), - E->getNameInfo(), E->getType(), E->getValueKind()); - } - return BaseTransform::TransformDeclRefExpr(E); - } -}; +static ExprResult +tryBuildCapture(Sema &SemaRef, Expr *Capture, + llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { + if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) + return SemaRef.PerformImplicitConversion( + Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, + /*AllowExplicit=*/true); + auto I = Captures.find(Capture); + if (I != Captures.end()) + return buildCapture(SemaRef, Capture, I->second); + DeclRefExpr *Ref = nullptr; + ExprResult Res = buildCapture(SemaRef, Capture, Ref); + Captures[Capture] = Ref; + return Res; } /// \brief Build the expression to calculate the number of iterations. -Expr * -OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S, - const bool LimitedType) const { - TransformToNewDefs Transform(SemaRef); +Expr *OpenMPIterationSpaceChecker::BuildNumIterations( + Scope *S, const bool LimitedType, + llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { ExprResult Diff; auto VarType = Var->getType().getNonReferenceType(); if (VarType->isIntegerType() || VarType->isPointerType() || @@ -3676,24 +3655,8 @@ OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S, // Upper - Lower auto *UBExpr = TestIsLessOp ? UB : LB; auto *LBExpr = TestIsLessOp ? LB : UB; - Expr *Upper = Transform.TransformExpr(UBExpr).get(); - Expr *Lower = Transform.TransformExpr(LBExpr).get(); - if (!Upper || !Lower) - return nullptr; - if (!SemaRef.Context.hasSameType(Upper->getType(), UBExpr->getType())) { - Upper = SemaRef - .PerformImplicitConversion(Upper, UBExpr->getType(), - Sema::AA_Converting, - /*AllowExplicit=*/true) - .get(); - } - if (!SemaRef.Context.hasSameType(Lower->getType(), LBExpr->getType())) { - Lower = SemaRef - .PerformImplicitConversion(Lower, LBExpr->getType(), - Sema::AA_Converting, - /*AllowExplicit=*/true) - .get(); - } + Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); + Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); if (!Upper || !Lower) return nullptr; @@ -3720,18 +3683,9 @@ OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S, return nullptr; // Upper - Lower [- 1] + Step - auto *StepNoImp = Step->IgnoreImplicit(); - auto NewStep = Transform.TransformExpr(StepNoImp); - if (NewStep.isInvalid()) + auto NewStep = tryBuildCapture(SemaRef, Step, Captures); + if (!NewStep.isUsable()) return nullptr; - if (!SemaRef.Context.hasSameType(NewStep.get()->getType(), - StepNoImp->getType())) { - NewStep = SemaRef.PerformImplicitConversion( - NewStep.get(), StepNoImp->getType(), Sema::AA_Converting, - /*AllowExplicit=*/true); - if (NewStep.isInvalid()) - return nullptr; - } Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); if (!Diff.isUsable()) return nullptr; @@ -3742,17 +3696,6 @@ OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S, return nullptr; // (Upper - Lower [- 1] + Step) / Step - NewStep = Transform.TransformExpr(StepNoImp); - if (NewStep.isInvalid()) - return nullptr; - if (!SemaRef.Context.hasSameType(NewStep.get()->getType(), - StepNoImp->getType())) { - NewStep = SemaRef.PerformImplicitConversion( - NewStep.get(), StepNoImp->getType(), Sema::AA_Converting, - /*AllowExplicit=*/true); - if (NewStep.isInvalid()) - return nullptr; - } Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); if (!Diff.isUsable()) return nullptr; @@ -3798,35 +3741,25 @@ OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S, return Diff.get(); } -Expr *OpenMPIterationSpaceChecker::BuildPreCond(Scope *S, Expr *Cond) const { +Expr *OpenMPIterationSpaceChecker::BuildPreCond( + Scope *S, Expr *Cond, + llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { // Try to build LB <op> UB, where <op> is <, >, <=, or >=. bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); - TransformToNewDefs Transform(SemaRef); - - auto NewLB = Transform.TransformExpr(LB); - auto NewUB = Transform.TransformExpr(UB); - if (NewLB.isInvalid() || NewUB.isInvalid()) - return Cond; - if (!SemaRef.Context.hasSameType(NewLB.get()->getType(), LB->getType())) { - NewLB = SemaRef.PerformImplicitConversion(NewLB.get(), LB->getType(), - Sema::AA_Converting, - /*AllowExplicit=*/true); - } - if (!SemaRef.Context.hasSameType(NewUB.get()->getType(), UB->getType())) { - NewUB = SemaRef.PerformImplicitConversion(NewUB.get(), UB->getType(), - Sema::AA_Converting, - /*AllowExplicit=*/true); - } - if (NewLB.isInvalid() || NewUB.isInvalid()) - return Cond; + + auto NewLB = tryBuildCapture(SemaRef, LB, Captures); + auto NewUB = tryBuildCapture(SemaRef, UB, Captures); + if (!NewLB.isUsable() || !NewUB.isUsable()) + return nullptr; + auto CondExpr = SemaRef.BuildBinOp( S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE) : (TestIsStrictOp ? BO_GT : BO_GE), NewLB.get(), NewUB.get()); if (CondExpr.isUsable()) { - if (!SemaRef.Context.hasSameType(CondExpr.get()->getType(), - SemaRef.Context.BoolTy)) + if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), + SemaRef.Context.BoolTy)) CondExpr = SemaRef.PerformImplicitConversion( CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, /*AllowExplicit=*/true); @@ -3909,7 +3842,8 @@ static bool CheckOpenMPIterationSpace( unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA, - LoopIterationSpace &ResultIterSpace) { + LoopIterationSpace &ResultIterSpace, + llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { // OpenMP [2.6, Canonical Loop Form] // for (init-expr; test-expr; incr-expr) structured-block auto For = dyn_cast_or_null<ForStmt>(S); @@ -4027,11 +3961,13 @@ static bool CheckOpenMPIterationSpace( return HasErrors; // Build the loop's iteration space representation. - ResultIterSpace.PreCond = ISC.BuildPreCond(DSA.getCurScope(), For->getCond()); + ResultIterSpace.PreCond = + ISC.BuildPreCond(DSA.getCurScope(), For->getCond(), Captures); ResultIterSpace.NumIterations = ISC.BuildNumIterations( - DSA.getCurScope(), (isOpenMPWorksharingDirective(DKind) || - isOpenMPTaskLoopDirective(DKind) || - isOpenMPDistributeDirective(DKind))); + DSA.getCurScope(), + (isOpenMPWorksharingDirective(DKind) || + isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), + Captures); ResultIterSpace.CounterVar = ISC.BuildCounterVar(); ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar(); ResultIterSpace.CounterInit = ISC.BuildCounterInit(); @@ -4052,23 +3988,15 @@ static bool CheckOpenMPIterationSpace( } /// \brief Build 'VarRef = Start. -static ExprResult BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, - ExprResult VarRef, ExprResult Start) { - TransformToNewDefs Transform(SemaRef); +static ExprResult +BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, + ExprResult Start, + llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { // Build 'VarRef = Start. - auto *StartNoImp = Start.get()->IgnoreImplicit(); - auto NewStart = Transform.TransformExpr(StartNoImp); - if (NewStart.isInvalid()) + auto NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); + if (!NewStart.isUsable()) return ExprError(); if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), - StartNoImp->getType())) { - NewStart = SemaRef.PerformImplicitConversion( - NewStart.get(), StartNoImp->getType(), Sema::AA_Converting, - /*AllowExplicit=*/true); - if (NewStart.isInvalid()) - return ExprError(); - } - if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), VarRef.get()->getType())) { NewStart = SemaRef.PerformImplicitConversion( NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, @@ -4083,29 +4011,22 @@ static ExprResult BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, } /// \brief Build 'VarRef = Start + Iter * Step'. -static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S, - SourceLocation Loc, ExprResult VarRef, - ExprResult Start, ExprResult Iter, - ExprResult Step, bool Subtract) { +static ExprResult +BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, + ExprResult VarRef, ExprResult Start, ExprResult Iter, + ExprResult Step, bool Subtract, + llvm::MapVector<Expr *, DeclRefExpr *> *Captures = nullptr) { // Add parentheses (for debugging purposes only). Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || !Step.isUsable()) return ExprError(); - auto *StepNoImp = Step.get()->IgnoreImplicit(); - TransformToNewDefs Transform(SemaRef); - auto NewStep = Transform.TransformExpr(StepNoImp); + ExprResult NewStep = Step; + if (Captures) + NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); if (NewStep.isInvalid()) return ExprError(); - if (!SemaRef.Context.hasSameType(NewStep.get()->getType(), - StepNoImp->getType())) { - NewStep = SemaRef.PerformImplicitConversion( - NewStep.get(), StepNoImp->getType(), Sema::AA_Converting, - /*AllowExplicit=*/true); - if (NewStep.isInvalid()) - return ExprError(); - } ExprResult Update = SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); if (!Update.isUsable()) @@ -4113,18 +4034,11 @@ static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S, // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or // 'VarRef = Start (+|-) Iter * Step'. - auto *StartNoImp = Start.get()->IgnoreImplicit(); - auto NewStart = Transform.TransformExpr(StartNoImp); + ExprResult NewStart = Start; + if (Captures) + NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); if (NewStart.isInvalid()) return ExprError(); - if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), - StartNoImp->getType())) { - NewStart = SemaRef.PerformImplicitConversion( - NewStart.get(), StartNoImp->getType(), Sema::AA_Converting, - /*AllowExplicit=*/true); - if (NewStart.isInvalid()) - return ExprError(); - } // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. ExprResult SavedUpdate = Update; @@ -4196,6 +4110,49 @@ static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) { return false; } +/// Build preinits statement for the given declarations. +static Stmt *buildPreInits(ASTContext &Context, + SmallVectorImpl<Decl *> &PreInits) { + if (!PreInits.empty()) { + return new (Context) DeclStmt( + DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), + SourceLocation(), SourceLocation()); + } + return nullptr; +} + +/// Build preinits statement for the given declarations. +static Stmt *buildPreInits(ASTContext &Context, + llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { + if (!Captures.empty()) { + SmallVector<Decl *, 16> PreInits; + for (auto &Pair : Captures) + PreInits.push_back(Pair.second->getDecl()); + return buildPreInits(Context, PreInits); + } + return nullptr; +} + +/// Build postupdate expression for the given list of postupdates expressions. +static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { + Expr *PostUpdate = nullptr; + if (!PostUpdates.empty()) { + for (auto *E : PostUpdates) { + Expr *ConvE = S.BuildCStyleCastExpr( + E->getExprLoc(), + S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), + E->getExprLoc(), E) + .get(); + PostUpdate = PostUpdate + ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, + PostUpdate, ConvE) + .get() + : ConvE; + } + } + return PostUpdate; +} + /// \brief Called on a for stmt to check itself and nested loops (if any). /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, /// number of collapsed loops otherwise. @@ -4229,6 +4186,7 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, } // This is helper routine for loop directives (e.g., 'for', 'simd', // 'for simd', etc.). + llvm::MapVector<Expr *, DeclRefExpr *> Captures; SmallVector<LoopIterationSpace, 4> IterSpaces; IterSpaces.resize(NestedLoopCount); Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); @@ -4236,7 +4194,7 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, CollapseLoopCountExpr, OrderedLoopCountExpr, VarsWithImplicitDSA, - IterSpaces[Cnt])) + IterSpaces[Cnt], Captures)) return 0; // Move on to the next nested for loop, or to the loop body. // OpenMP [2.8.1, simd construct, Restrictions] @@ -4358,19 +4316,13 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); ExprResult CalcLastIteration; if (!IsConstant) { - SourceLocation SaveLoc; - VarDecl *SaveVar = - buildVarDecl(SemaRef, SaveLoc, LastIteration.get()->getType(), - ".omp.last.iteration"); - ExprResult SaveRef = buildDeclRefExpr( - SemaRef, SaveVar, LastIteration.get()->getType(), SaveLoc); - CalcLastIteration = SemaRef.BuildBinOp(CurScope, SaveLoc, BO_Assign, - SaveRef.get(), LastIteration.get()); + ExprResult SaveRef = + tryBuildCapture(SemaRef, LastIteration.get(), Captures); LastIteration = SaveRef; // Prepare SaveRef + 1. NumIterations = SemaRef.BuildBinOp( - CurScope, SaveLoc, BO_Add, SaveRef.get(), + CurScope, SourceLocation(), BO_Add, SaveRef.get(), SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); if (!NumIterations.isUsable()) return 0; @@ -4525,14 +4477,14 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), /*RefersToCapture=*/true); ExprResult Init = BuildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, - IS.CounterInit); + IS.CounterInit, Captures); if (!Init.isUsable()) { HasErrors = true; break; } - ExprResult Update = - BuildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, - IS.CounterInit, Iter, IS.CounterStep, IS.Subtract); + ExprResult Update = BuildCounterUpdate( + SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, + IS.CounterStep, IS.Subtract, &Captures); if (!Update.isUsable()) { HasErrors = true; break; @@ -4541,7 +4493,7 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step ExprResult Final = BuildCounterUpdate( SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, - IS.NumIterations, IS.CounterStep, IS.Subtract); + IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); if (!Final.isUsable()) { HasErrors = true; break; @@ -4586,6 +4538,7 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Built.CalcLastIteration = SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get(); Built.PreCond = PreCond.get(); + Built.PreInits = buildPreInits(C, Captures); Built.Cond = Cond.get(); Built.Init = Init.get(); Built.Inc = Inc.get(); @@ -6201,6 +6154,16 @@ StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( assert((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built"); + if (!CurContext->isDependentContext()) { + // Finalize the clauses that need pre-built expressions for CodeGen. + for (auto C : Clauses) { + if (auto LC = dyn_cast<OMPLinearClause>(C)) + if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), + B.NumIterations, *this, CurScope)) + return StmtError(); + } + } + // OpenMP, [2.9.2 taskloop Construct, Restrictions] // The grainsize clause and num_tasks clause are mutually exclusive and may // not appear on the same taskloop directive. @@ -6847,13 +6810,9 @@ OMPClause *Sema::ActOnOpenMPScheduleClause( return nullptr; } } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { - ValExpr = buildCapture(*this, ValExpr); - Decl *D = cast<DeclRefExpr>(ValExpr)->getDecl(); - HelperValStmt = - new (Context) DeclStmt(DeclGroupRef::Create(Context, &D, - /*NumDecls=*/1), - SourceLocation(), SourceLocation()); - ValExpr = DefaultLvalueConversion(ValExpr).get(); + llvm::MapVector<Expr *, DeclRefExpr *> Captures; + ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); + HelperValStmt = buildPreInits(Context, Captures); } } } @@ -7569,16 +7528,10 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, if (Vars.empty()) return nullptr; - Stmt *PreInit = nullptr; - if (!ExprCaptures.empty()) { - PreInit = new (Context) - DeclStmt(DeclGroupRef::Create(Context, ExprCaptures.begin(), - ExprCaptures.size()), - SourceLocation(), SourceLocation()); - } return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, - Vars, PrivateCopies, Inits, PreInit); + Vars, PrivateCopies, Inits, + buildPreInits(Context, ExprCaptures)); } OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, @@ -7730,27 +7683,11 @@ OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, if (Vars.empty()) return nullptr; - Stmt *PreInit = nullptr; - if (!ExprCaptures.empty()) { - PreInit = new (Context) - DeclStmt(DeclGroupRef::Create(Context, ExprCaptures.begin(), - ExprCaptures.size()), - SourceLocation(), SourceLocation()); - } - Expr *PostUpdate = nullptr; - if (!ExprPostUpdates.empty()) { - for (auto *E : ExprPostUpdates) { - ExprResult PostUpdateRes = - PostUpdate - ? CreateBuiltinBinOp(SourceLocation(), BO_Comma, PostUpdate, E) - : E; - PostUpdate = PostUpdateRes.get(); - } - } return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, SrcExprs, DstExprs, AssignmentOps, - PreInit, PostUpdate); + buildPreInits(Context, ExprCaptures), + buildPostUpdate(*this, ExprPostUpdates)); } OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, @@ -8482,20 +8419,20 @@ OMPClause *Sema::ActOnOpenMPReductionClause( } else { VarsExpr = Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); - if (!IsOpenMPCapturedDecl(D)) { - ExprCaptures.push_back(Ref->getDecl()); - if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { - ExprResult RefRes = DefaultLvalueConversion(Ref); - if (!RefRes.isUsable()) - continue; - ExprResult PostUpdateRes = - BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, - SimpleRefExpr, RefRes.get()); - if (!PostUpdateRes.isUsable()) - continue; - ExprPostUpdates.push_back( - IgnoredValueConversions(PostUpdateRes.get()).get()); - } + } + if (!IsOpenMPCapturedDecl(D)) { + ExprCaptures.push_back(Ref->getDecl()); + if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { + ExprResult RefRes = DefaultLvalueConversion(Ref); + if (!RefRes.isUsable()) + continue; + ExprResult PostUpdateRes = + BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, + SimpleRefExpr, RefRes.get()); + if (!PostUpdateRes.isUsable()) + continue; + ExprPostUpdates.push_back( + IgnoredValueConversions(PostUpdateRes.get()).get()); } } } @@ -8509,28 +8446,12 @@ OMPClause *Sema::ActOnOpenMPReductionClause( if (Vars.empty()) return nullptr; - Stmt *PreInit = nullptr; - if (!ExprCaptures.empty()) { - PreInit = new (Context) - DeclStmt(DeclGroupRef::Create(Context, ExprCaptures.begin(), - ExprCaptures.size()), - SourceLocation(), SourceLocation()); - } - Expr *PostUpdate = nullptr; - if (!ExprPostUpdates.empty()) { - for (auto *E : ExprPostUpdates) { - ExprResult PostUpdateRes = - PostUpdate - ? CreateBuiltinBinOp(SourceLocation(), BO_Comma, PostUpdate, E) - : E; - PostUpdate = PostUpdateRes.get(); - } - } return OMPReductionClause::Create( Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, Privates, - LHSs, RHSs, ReductionOps, PreInit, PostUpdate); + LHSs, RHSs, ReductionOps, buildPreInits(Context, ExprCaptures), + buildPostUpdate(*this, ExprPostUpdates)); } OMPClause *Sema::ActOnOpenMPLinearClause( @@ -8696,32 +8617,16 @@ OMPClause *Sema::ActOnOpenMPLinearClause( } } - Stmt *PreInit = nullptr; - if (!ExprCaptures.empty()) { - PreInit = new (Context) - DeclStmt(DeclGroupRef::Create(Context, ExprCaptures.begin(), - ExprCaptures.size()), - SourceLocation(), SourceLocation()); - } - Expr *PostUpdate = nullptr; - if (!ExprPostUpdates.empty()) { - for (auto *E : ExprPostUpdates) { - ExprResult PostUpdateRes = - PostUpdate - ? CreateBuiltinBinOp(SourceLocation(), BO_Comma, PostUpdate, E) - : E; - PostUpdate = PostUpdateRes.get(); - } - } - return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, ColonLoc, EndLoc, Vars, Privates, Inits, - StepExpr, CalcStepExpr, PreInit, PostUpdate); + StepExpr, CalcStepExpr, + buildPreInits(Context, ExprCaptures), + buildPostUpdate(*this, ExprPostUpdates)); } -static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, - Expr *NumIterations, Sema &SemaRef, - Scope *S) { +static bool +FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, + Expr *NumIterations, Sema &SemaRef, Scope *S) { // Walk the vars and build update/final expressions for the CodeGen. SmallVector<Expr *, 8> Updates; SmallVector<Expr *, 8> Finals; @@ -8731,8 +8636,9 @@ static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, // If linear-step is not specified it is assumed to be 1. if (Step == nullptr) Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); - else if (CalcStep) + else if (CalcStep) { Step = cast<BinaryOperator>(CalcStep)->getLHS(); + } bool HasErrors = false; auto CurInit = Clause.inits().begin(); auto CurPrivate = Clause.privates().begin(); @@ -10315,13 +10221,9 @@ OMPClause *Sema::ActOnOpenMPDistScheduleClause( return nullptr; } } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { - ValExpr = buildCapture(*this, ValExpr); - Decl *D = cast<DeclRefExpr>(ValExpr)->getDecl(); - HelperValStmt = - new (Context) DeclStmt(DeclGroupRef::Create(Context, &D, - /*NumDecls=*/1), - SourceLocation(), SourceLocation()); - ValExpr = DefaultLvalueConversion(ValExpr).get(); + llvm::MapVector<Expr *, DeclRefExpr *> Captures; + ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); + HelperValStmt = buildPreInits(Context, Captures); } } } diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index f8fb2b86034..2de0b58fa4a 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -2310,6 +2310,7 @@ void ASTStmtReader::VisitOMPLoopDirective(OMPLoopDirective *D) { D->setCond(Reader.ReadSubExpr()); D->setInit(Reader.ReadSubExpr()); D->setInc(Reader.ReadSubExpr()); + D->setPreInits(Reader.ReadSubStmt()); if (isOpenMPWorksharingDirective(D->getDirectiveKind()) || isOpenMPTaskLoopDirective(D->getDirectiveKind()) || isOpenMPDistributeDirective(D->getDirectiveKind())) { diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 3738c8e9a78..a29a3007ed6 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -2097,6 +2097,7 @@ void ASTStmtWriter::VisitOMPLoopDirective(OMPLoopDirective *D) { Writer.AddStmt(D->getCond()); Writer.AddStmt(D->getInit()); Writer.AddStmt(D->getInc()); + Writer.AddStmt(D->getPreInits()); if (isOpenMPWorksharingDirective(D->getDirectiveKind()) || isOpenMPTaskLoopDirective(D->getDirectiveKind()) || isOpenMPDistributeDirective(D->getDirectiveKind())) { diff --git a/clang/test/OpenMP/distribute_codegen.cpp b/clang/test/OpenMP/distribute_codegen.cpp index ab5684c51f8..f15a62c59bc 100644 --- a/clang/test/OpenMP/distribute_codegen.cpp +++ b/clang/test/OpenMP/distribute_codegen.cpp @@ -224,8 +224,10 @@ void test_precond() { // ..many loads of %0.. // CHECK: [[A2:%.+]] = load i8*, i8** [[APTRADDR]] // CHECK: [[AVAL0:%.+]] = load i8, i8* [[A2]] -// CHECK: [[AVAL1:%.+]] = load i8, i8* [[A2]] -// CHECK: [[AVAL2:%.+]] = load i8, i8* [[A2]] +// CHECK: store i8 [[AVAL0]], i8* [[CAP_EXPR:%.+]], +// CHECK: [[AVAL1:%.+]] = load i8, i8* [[CAP_EXPR]] +// CHECK: load i8, i8* [[CAP_EXPR]] +// CHECK: [[AVAL2:%.+]] = load i8, i8* [[CAP_EXPR]] // CHECK: [[ACONV:%.+]] = sext i8 [[AVAL2]] to i32 // CHECK: [[ACMP:%.+]] = icmp slt i32 [[ACONV]], 10 // CHECK: br i1 [[ACMP]], label %[[PRECOND_THEN:.+]], label %[[PRECOND_END:.+]] diff --git a/clang/test/OpenMP/for_codegen.cpp b/clang/test/OpenMP/for_codegen.cpp index 98761f56c76..df6ae0f3f79 100644 --- a/clang/test/OpenMP/for_codegen.cpp +++ b/clang/test/OpenMP/for_codegen.cpp @@ -327,12 +327,13 @@ void runtime(float *a, float *b, float *c, float *d) { // CHECK-LABEL: test_precond void test_precond() { // CHECK: [[A_ADDR:%.+]] = alloca i8, + // CHECK: [[CAP:%.+]] = alloca i8, // CHECK: [[I_ADDR:%.+]] = alloca i8, char a = 0; // CHECK: store i8 0, // CHECK: store i32 // CHECK: store i8 - // CHECK: [[A:%.+]] = load i8, i8* [[A_ADDR]], + // CHECK: [[A:%.+]] = load i8, i8* [[CAP]], // CHECK: [[CONV:%.+]] = sext i8 [[A]] to i32 // CHECK: [[CMP:%.+]] = icmp slt i32 [[CONV]], 10 // CHECK: br i1 [[CMP]], label %[[PRECOND_THEN:[^,]+]], label %[[PRECOND_END:[^,]+]] diff --git a/clang/test/OpenMP/for_loop_messages.cpp b/clang/test/OpenMP/for_loop_messages.cpp index 019b9849b38..bb58a77e5ad 100644 --- a/clang/test/OpenMP/for_loop_messages.cpp +++ b/clang/test/OpenMP/for_loop_messages.cpp @@ -439,12 +439,12 @@ public: typedef int difference_type; typedef std::random_access_iterator_tag iterator_category; }; -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} int operator-(GoodIter a, GoodIter b) { return 0; } // expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}} GoodIter operator-(GoodIter a) { return a; } -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} GoodIter operator-(GoodIter a, int v) { return GoodIter(); } // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}} @@ -495,7 +495,7 @@ int test_with_random_access_iterator() { #pragma omp for for (begin = GoodIter(0); begin < end; ++begin) ++begin; -// expected-error@+4 {{invalid operands to binary expression ('GoodIter' and 'Iter0')}} +// expected-error@+4 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}} // expected-error@+3 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} #pragma omp parallel #pragma omp for diff --git a/clang/test/OpenMP/for_simd_loop_messages.cpp b/clang/test/OpenMP/for_simd_loop_messages.cpp index afd7b0bb545..e9729a8fc26 100644 --- a/clang/test/OpenMP/for_simd_loop_messages.cpp +++ b/clang/test/OpenMP/for_simd_loop_messages.cpp @@ -408,12 +408,12 @@ public: typedef int difference_type; typedef std::random_access_iterator_tag iterator_category; }; -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} int operator-(GoodIter a, GoodIter b) { return 0; } // expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}} GoodIter operator-(GoodIter a) { return a; } -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} GoodIter operator-(GoodIter a, int v) { return GoodIter(); } // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}} @@ -465,7 +465,7 @@ int test_with_random_access_iterator() { for (begin = GoodIter(0); begin < end; ++begin) ++begin; #pragma omp parallel -// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'Iter0')}} +// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}} // expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} #pragma omp for simd for (begin = begin0; begin < end; ++begin) diff --git a/clang/test/OpenMP/parallel_for_loop_messages.cpp b/clang/test/OpenMP/parallel_for_loop_messages.cpp index 2bb32bdfc17..7e136e75869 100644 --- a/clang/test/OpenMP/parallel_for_loop_messages.cpp +++ b/clang/test/OpenMP/parallel_for_loop_messages.cpp @@ -354,12 +354,12 @@ public: typedef int difference_type; typedef std::random_access_iterator_tag iterator_category; }; -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} int operator-(GoodIter a, GoodIter b) { return 0; } // expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}} GoodIter operator-(GoodIter a) { return a; } -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} GoodIter operator-(GoodIter a, int v) { return GoodIter(); } // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}} @@ -402,7 +402,7 @@ int test_with_random_access_iterator() { #pragma omp parallel for for (begin = GoodIter(0); begin < end; ++begin) ++begin; -// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'Iter0')}} +// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}} // expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} #pragma omp parallel for for (begin = begin0; begin < end; ++begin) diff --git a/clang/test/OpenMP/parallel_for_simd_loop_messages.cpp b/clang/test/OpenMP/parallel_for_simd_loop_messages.cpp index e5fd8c04c0c..403e951d53c 100644 --- a/clang/test/OpenMP/parallel_for_simd_loop_messages.cpp +++ b/clang/test/OpenMP/parallel_for_simd_loop_messages.cpp @@ -355,12 +355,12 @@ public: typedef int difference_type; typedef std::random_access_iterator_tag iterator_category; }; -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} int operator-(GoodIter a, GoodIter b) { return 0; } // expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}} GoodIter operator-(GoodIter a) { return a; } -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} GoodIter operator-(GoodIter a, int v) { return GoodIter(); } // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}} @@ -403,7 +403,7 @@ int test_with_random_access_iterator() { #pragma omp parallel for simd for (begin = GoodIter(0); begin < end; ++begin) ++begin; -// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'Iter0')}} +// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}} // expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} #pragma omp parallel for simd for (begin = begin0; begin < end; ++begin) diff --git a/clang/test/OpenMP/simd_codegen.cpp b/clang/test/OpenMP/simd_codegen.cpp index 62028339f51..6d78766d03a 100644 --- a/clang/test/OpenMP/simd_codegen.cpp +++ b/clang/test/OpenMP/simd_codegen.cpp @@ -321,7 +321,6 @@ public: // CHECK-LABEL: define {{.*void}} @{{.*}}iter_simple{{.*}} void iter_simple(IterDouble ia, IterDouble ib, IterDouble ic) { // -// CHECK: store i32 0, i32* [[IT_OMP_IV:%[^,]+]] // Calculate number of iterations before the loop body. // CHECK: [[DIFF1:%.+]] = invoke {{.*}}i32 @{{.*}}IterDouble{{.*}} // CHECK: [[DIFF2:%.+]] = sub nsw i32 [[DIFF1]], 1 @@ -329,6 +328,7 @@ void iter_simple(IterDouble ia, IterDouble ib, IterDouble ic) { // CHECK-NEXT: [[DIFF4:%.+]] = sdiv i32 [[DIFF3]], 1 // CHECK-NEXT: [[DIFF5:%.+]] = sub nsw i32 [[DIFF4]], 1 // CHECK-NEXT: store i32 [[DIFF5]], i32* [[OMP_LAST_IT:%[^,]+]]{{.+}} +// CHECK: store i32 0, i32* [[IT_OMP_IV:%[^,]+]] #pragma omp simd // CHECK: [[IV:%.+]] = load i32, i32* [[IT_OMP_IV]]{{.+}} !llvm.mem.parallel_loop_access ![[ITER_LOOP_ID:[0-9]+]] diff --git a/clang/test/OpenMP/target_parallel_for_loop_messages.cpp b/clang/test/OpenMP/target_parallel_for_loop_messages.cpp index 5d9abed4c00..0e8eab10b5c 100644 --- a/clang/test/OpenMP/target_parallel_for_loop_messages.cpp +++ b/clang/test/OpenMP/target_parallel_for_loop_messages.cpp @@ -354,12 +354,12 @@ public: typedef int difference_type; typedef std::random_access_iterator_tag iterator_category; }; -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} int operator-(GoodIter a, GoodIter b) { return 0; } // expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}} GoodIter operator-(GoodIter a) { return a; } -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} GoodIter operator-(GoodIter a, int v) { return GoodIter(); } // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}} @@ -402,7 +402,7 @@ int test_with_random_access_iterator() { #pragma omp target parallel for for (begin = GoodIter(0); begin < end; ++begin) ++begin; -// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'Iter0')}} +// expected-error@+3 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}} // expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} #pragma omp target parallel for for (begin = begin0; begin < end; ++begin) diff --git a/clang/test/OpenMP/taskloop_loop_messages.cpp b/clang/test/OpenMP/taskloop_loop_messages.cpp index 02518e572f3..291cbdbe718 100644 --- a/clang/test/OpenMP/taskloop_loop_messages.cpp +++ b/clang/test/OpenMP/taskloop_loop_messages.cpp @@ -427,12 +427,12 @@ public: typedef int difference_type; typedef std::random_access_iterator_tag iterator_category; }; -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} int operator-(GoodIter a, GoodIter b) { return 0; } // expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}} GoodIter operator-(GoodIter a) { return a; } -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} GoodIter operator-(GoodIter a, int v) { return GoodIter(); } // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}} @@ -483,7 +483,7 @@ int test_with_random_access_iterator() { #pragma omp taskloop for (begin = GoodIter(0); begin < end; ++begin) ++begin; -// expected-error@+4 {{invalid operands to binary expression ('GoodIter' and 'Iter0')}} +// expected-error@+4 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}} // expected-error@+3 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} #pragma omp parallel #pragma omp taskloop diff --git a/clang/test/OpenMP/taskloop_simd_loop_messages.cpp b/clang/test/OpenMP/taskloop_simd_loop_messages.cpp index 47318721102..3326e6ff61c 100644 --- a/clang/test/OpenMP/taskloop_simd_loop_messages.cpp +++ b/clang/test/OpenMP/taskloop_simd_loop_messages.cpp @@ -428,12 +428,12 @@ public: typedef int difference_type; typedef std::random_access_iterator_tag iterator_category; }; -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'GoodIter' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} int operator-(GoodIter a, GoodIter b) { return 0; } // expected-note@+1 3 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}} GoodIter operator-(GoodIter a) { return a; } -// expected-note@+2 {{candidate function not viable: no known conversion from 'Iter0' to 'int' for 2nd argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'const Iter0' to 'int' for 2nd argument}} // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}} GoodIter operator-(GoodIter a, int v) { return GoodIter(); } // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter0' to 'GoodIter' for 1st argument}} @@ -484,7 +484,7 @@ int test_with_random_access_iterator() { #pragma omp taskloop simd for (begin = GoodIter(0); begin < end; ++begin) ++begin; -// expected-error@+4 {{invalid operands to binary expression ('GoodIter' and 'Iter0')}} +// expected-error@+4 {{invalid operands to binary expression ('GoodIter' and 'const Iter0')}} // expected-error@+3 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}} #pragma omp parallel #pragma omp taskloop simd |