[clang] 567a660 - [OpenMP 5.2] Initial parsing and semantic analysis suppport for 'step' modifier on 'linear' clause

Fazlay Rabbi via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 24 15:30:05 PDT 2023


Author: Fazlay Rabbi
Date: 2023-10-24T15:04:23-07:00
New Revision: 567a660a252323f2e82abaf48752dcad26d4779e

URL: https://github.com/llvm/llvm-project/commit/567a660a252323f2e82abaf48752dcad26d4779e
DIFF: https://github.com/llvm/llvm-project/commit/567a660a252323f2e82abaf48752dcad26d4779e.diff

LOG: [OpenMP 5.2] Initial parsing and semantic analysis suppport for 'step' modifier on 'linear' clause

Reference:
(1) OpenMP 5.2 Specification - Seciton 5.4.6

Differential revision: https://reviews.llvm.org/D159546

Added: 
    

Modified: 
    clang/include/clang/AST/OpenMPClause.h
    clang/include/clang/Basic/DiagnosticParseKinds.td
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/include/clang/Basic/OpenMPKinds.def
    clang/include/clang/Sema/Sema.h
    clang/lib/AST/OpenMPClause.cpp
    clang/lib/Parse/ParseOpenMP.cpp
    clang/lib/Sema/SemaOpenMP.cpp
    clang/lib/Sema/TreeTransform.h
    clang/test/Analysis/cfg-openmp.cpp
    clang/test/OpenMP/declare_simd_messages.cpp
    clang/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp
    clang/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp
    clang/test/OpenMP/distribute_simd_ast_print.cpp
    clang/test/OpenMP/distribute_simd_linear_messages.cpp
    clang/test/OpenMP/for_ast_print.cpp
    clang/test/OpenMP/for_linear_messages.cpp
    clang/test/OpenMP/for_simd_ast_print.cpp
    clang/test/OpenMP/for_simd_linear_messages.cpp
    clang/test/OpenMP/masked_taskloop_simd_linear_messages.cpp
    clang/test/OpenMP/master_taskloop_simd_linear_messages.cpp
    clang/test/OpenMP/parallel_for_ast_print.cpp
    clang/test/OpenMP/parallel_for_linear_messages.cpp
    clang/test/OpenMP/parallel_for_simd_ast_print.cpp
    clang/test/OpenMP/parallel_for_simd_linear_messages.cpp
    clang/test/OpenMP/parallel_masked_taskloop_simd_ast_print.cpp
    clang/test/OpenMP/parallel_masked_taskloop_simd_linear_messages.cpp
    clang/test/OpenMP/parallel_master_taskloop_simd_ast_print.cpp
    clang/test/OpenMP/parallel_master_taskloop_simd_linear_messages.cpp
    clang/test/OpenMP/simd_ast_print.cpp
    clang/test/OpenMP/simd_linear_messages.cpp
    clang/test/OpenMP/target_parallel_for_ast_print.cpp
    clang/test/OpenMP/target_parallel_for_linear_messages.cpp
    clang/test/OpenMP/target_parallel_for_simd_ast_print.cpp
    clang/test/OpenMP/target_parallel_for_simd_linear_messages.cpp
    clang/test/OpenMP/target_simd_ast_print.cpp
    clang/test/OpenMP/target_simd_linear_messages.cpp
    clang/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp
    clang/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp
    clang/test/OpenMP/taskloop_simd_linear_messages.cpp
    clang/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp
    clang/test/OpenMP/teams_distribute_simd_linear_messages.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h
index eeeca1998f9fa9c..549f12e87df597a 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -3918,6 +3918,9 @@ class OMPLinearClause final
   /// Location of ':'.
   SourceLocation ColonLoc;
 
+  /// Location of 'step' modifier.
+  SourceLocation StepModifierLoc;
+
   /// Sets the linear step for clause.
   void setStep(Expr *Step) { *(getFinals().end()) = Step; }
 
@@ -3929,16 +3932,18 @@ class OMPLinearClause final
   /// \param StartLoc Starting location of the clause.
   /// \param LParenLoc Location of '('.
   /// \param ColonLoc Location of ':'.
+  /// \param StepModifierLoc Location of 'step' modifier.
   /// \param EndLoc Ending location of the clause.
   /// \param NumVars Number of variables.
   OMPLinearClause(SourceLocation StartLoc, SourceLocation LParenLoc,
                   OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
-                  SourceLocation ColonLoc, SourceLocation EndLoc,
-                  unsigned NumVars)
+                  SourceLocation ColonLoc, SourceLocation StepModifierLoc,
+                  SourceLocation EndLoc, unsigned NumVars)
       : OMPVarListClause<OMPLinearClause>(llvm::omp::OMPC_linear, StartLoc,
                                           LParenLoc, EndLoc, NumVars),
         OMPClauseWithPostUpdate(this), Modifier(Modifier),
-        ModifierLoc(ModifierLoc), ColonLoc(ColonLoc) {}
+        ModifierLoc(ModifierLoc), ColonLoc(ColonLoc),
+        StepModifierLoc(StepModifierLoc) {}
 
   /// Build an empty clause.
   ///
@@ -4017,6 +4022,7 @@ class OMPLinearClause final
   /// \param Modifier Modifier of 'linear' clause.
   /// \param ModifierLoc Modifier location.
   /// \param ColonLoc Location of ':'.
+  /// \param StepModifierLoc Location of 'step' modifier.
   /// \param EndLoc Ending location of the clause.
   /// \param VL List of references to the variables.
   /// \param PL List of private copies of original variables.
@@ -4030,9 +4036,10 @@ class OMPLinearClause final
   static OMPLinearClause *
   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
          OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
-         SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
-         ArrayRef<Expr *> PL, ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep,
-         Stmt *PreInit, Expr *PostUpdate);
+         SourceLocation ColonLoc, SourceLocation StepModifierLoc,
+         SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> PL,
+         ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit,
+         Expr *PostUpdate);
 
   /// Creates an empty clause with the place for \a NumVars variables.
   ///
@@ -4055,9 +4062,15 @@ class OMPLinearClause final
   /// Sets the location of ':'.
   void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
 
+  /// Sets the location of 'step' modifier.
+  void setStepModifierLoc(SourceLocation Loc) { StepModifierLoc = Loc; }
+
   /// Returns the location of ':'.
   SourceLocation getColonLoc() const { return ColonLoc; }
 
+  /// Returns the location of 'step' modifier.
+  SourceLocation getStepModifierLoc() const { return StepModifierLoc; }
+
   /// Returns linear step.
   Expr *getStep() { return *(getFinals().end()); }
 

diff  --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 9d33b014d5fd8c3..d6652e6a610c1be 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1348,6 +1348,8 @@ def warn_pragma_omp_ignored : Warning<
 def warn_omp_extra_tokens_at_eol : Warning<
   "extra tokens at the end of '#pragma omp %0' are ignored">,
   InGroup<ExtraTokens>;
+def err_omp_multiple_step_or_linear_modifier : Error<
+  "multiple %select{'step size'|'linear modifier'}0 found in linear clause">; 
 def warn_pragma_expected_colon_r_paren : Warning<
   "missing ':' or ')' after %0 - ignoring">, InGroup<IgnoredPragmas>;
 def err_omp_unknown_directive : Error<

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 941034820d2ef20..a673ce726d6c220 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11028,6 +11028,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_step_simple_modifier_exclusive : Error<
+  "step simple modifier is exclusive and can't be use with 'val', 'uval' or 'ref' modifier">;
 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">;
 def err_omp_wrong_if_directive_name_modifier : Error<

diff  --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def
index c999b8b9c4ff590..272537b769742b5 100644
--- a/clang/include/clang/Basic/OpenMPKinds.def
+++ b/clang/include/clang/Basic/OpenMPKinds.def
@@ -131,6 +131,7 @@ OPENMP_DEPEND_KIND(inoutallmemory)
 OPENMP_LINEAR_KIND(val)
 OPENMP_LINEAR_KIND(ref)
 OPENMP_LINEAR_KIND(uval)
+OPENMP_LINEAR_KIND(step)
 
 // Modifiers for 'atomic_default_mem_order' clause.
 OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(seq_cst)

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 73fee208cbef17e..1e9752345ffd173 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -12307,6 +12307,8 @@ class Sema final {
     bool IsMapTypeImplicit = false;
     SourceLocation ExtraModifierLoc;
     SourceLocation OmpAllMemoryLoc;
+    SourceLocation
+        StepModifierLoc; /// 'step' modifier location for linear clause
   };
 
   OMPClause *ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
@@ -12371,11 +12373,11 @@ class Sema final {
       const DeclarationNameInfo &ReductionId,
       ArrayRef<Expr *> UnresolvedReductions = std::nullopt);
   /// Called on well-formed 'linear' clause.
-  OMPClause *
-  ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step,
-                          SourceLocation StartLoc, SourceLocation LParenLoc,
-                          OpenMPLinearClauseKind LinKind, SourceLocation LinLoc,
-                          SourceLocation ColonLoc, SourceLocation EndLoc);
+  OMPClause *ActOnOpenMPLinearClause(
+      ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
+      SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
+      SourceLocation LinLoc, SourceLocation ColonLoc,
+      SourceLocation StepModifierLoc, SourceLocation EndLoc);
   /// Called on well-formed 'aligned' clause.
   OMPClause *ActOnOpenMPAlignedClause(ArrayRef<Expr *> VarList,
                                       Expr *Alignment,

diff  --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index b95b4fce180e736..4e19339a1361e6f 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -583,15 +583,17 @@ void OMPLinearClause::setUsedExprs(ArrayRef<Expr *> UE) {
 OMPLinearClause *OMPLinearClause::Create(
     const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
     OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
-    SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
-    ArrayRef<Expr *> PL, ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep,
-    Stmt *PreInit, Expr *PostUpdate) {
+    SourceLocation ColonLoc, SourceLocation StepModifierLoc,
+    SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> PL,
+    ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit,
+    Expr *PostUpdate) {
   // Allocate space for 5 lists (Vars, Inits, Updates, Finals), 2 expressions
   // (Step and CalcStep), list of used expression + step.
   void *Mem =
       C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size() + 2 + VL.size() + 1));
-  OMPLinearClause *Clause = new (Mem) OMPLinearClause(
-      StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc, EndLoc, VL.size());
+  OMPLinearClause *Clause =
+      new (Mem) OMPLinearClause(StartLoc, LParenLoc, Modifier, ModifierLoc,
+                                ColonLoc, StepModifierLoc, EndLoc, VL.size());
   Clause->setVarRefs(VL);
   Clause->setPrivates(PL);
   Clause->setInits(IL);
@@ -2207,16 +2209,20 @@ void OMPClausePrinter::VisitOMPInReductionClause(OMPInReductionClause *Node) {
 void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {
   if (!Node->varlist_empty()) {
     OS << "linear";
+    VisitOMPClauseList(Node, '(');
+    if (Node->getModifierLoc().isValid() || Node->getStep() != nullptr) {
+      OS << ": ";
+    }
     if (Node->getModifierLoc().isValid()) {
-      OS << '('
-         << getOpenMPSimpleClauseTypeName(OMPC_linear, Node->getModifier());
+      OS << getOpenMPSimpleClauseTypeName(OMPC_linear, Node->getModifier());
     }
-    VisitOMPClauseList(Node, '(');
-    if (Node->getModifierLoc().isValid())
-      OS << ')';
     if (Node->getStep() != nullptr) {
-      OS << ": ";
+      if (Node->getModifierLoc().isValid()) {
+        OS << ", ";
+      }
+      OS << "step(";
       Node->getStep()->printPretty(OS, nullptr, Policy, 0);
+      OS << ")";
     }
     OS << ")";
   }

diff  --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 1a80bce0cfde53c..4f3b8a28ee47ef3 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -4401,6 +4401,25 @@ bool Parser::ParseOpenMPReservedLocator(OpenMPClauseKind Kind,
   return false;
 }
 
+/// Parse step size expression. Returns true if parsing is successfull,
+/// otherwise returns false.
+static bool parseStepSize(Parser &P, Sema::OpenMPVarListDataTy &Data,
+                          OpenMPClauseKind CKind, SourceLocation ELoc) {
+  ExprResult Tail = P.ParseAssignmentExpression();
+  Sema &Actions = P.getActions();
+  Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc,
+                                     /*DiscardedValue*/ false);
+  if (Tail.isUsable()) {
+    Data.DepModOrTailExpr = Tail.get();
+    Token CurTok = P.getCurToken();
+    if (CurTok.isNot(tok::r_paren) && CurTok.isNot(tok::comma)) {
+      P.Diag(CurTok, diag::err_expected_punc) << "step expression";
+    }
+    return true;
+  }
+  return false;
+}
+
 /// Parses clauses with list.
 bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
                                 OpenMPClauseKind Kind,
@@ -4763,19 +4782,76 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
   if (NeedRParenForLinear)
     LinearT.consumeClose();
 
-  // Parse ':' linear-step (or ':' alignment).
+  // Parse ':' linear modifiers (val, uval, ref or step(step-size))
+  // or parse ':' alignment.
   const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
+  bool StepFound = false;
+  bool ModifierFound = false;
   if (MustHaveTail) {
     Data.ColonLoc = Tok.getLocation();
     SourceLocation ELoc = ConsumeToken();
-    ExprResult Tail = ParseAssignmentExpression();
-    Tail =
-        Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false);
-    if (Tail.isUsable())
-      Data.DepModOrTailExpr = Tail.get();
-    else
-      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
-                StopBeforeMatch);
+
+    if (getLangOpts().OpenMP >= 52 && Kind == OMPC_linear) {
+      while (Tok.isNot(tok::r_paren)) {
+        if (Tok.is(tok::identifier)) {
+          // identifier could be a linear kind (val, uval, ref) or step
+          // modifier or step size
+          OpenMPLinearClauseKind LinKind =
+              static_cast<OpenMPLinearClauseKind>(getOpenMPSimpleClauseType(
+                  Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok),
+                  getLangOpts()));
+
+          if (LinKind == OMPC_LINEAR_step) {
+            if (StepFound)
+              Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 0;
+
+            BalancedDelimiterTracker StepT(*this, tok::l_paren,
+                                           tok::annot_pragma_openmp_end);
+            SourceLocation StepModifierLoc = ConsumeToken();
+            // parse '('
+            if (StepT.consumeOpen())
+              Diag(StepModifierLoc, diag::err_expected_lparen_after) << "step";
+
+            // parse step size expression
+            StepFound = parseStepSize(*this, Data, Kind, Tok.getLocation());
+            if (StepFound)
+              Data.StepModifierLoc = StepModifierLoc;
+
+            // parse ')'
+            StepT.consumeClose();
+          } else if (LinKind >= 0 && LinKind < OMPC_LINEAR_step) {
+            if (ModifierFound)
+              Diag(Tok, diag::err_omp_multiple_step_or_linear_modifier) << 1;
+
+            Data.ExtraModifier = LinKind;
+            Data.ExtraModifierLoc = ConsumeToken();
+            ModifierFound = true;
+          } else {
+            StepFound = parseStepSize(*this, Data, Kind, Tok.getLocation());
+          }
+        } else {
+          // parse an integer expression as step size
+          StepFound = parseStepSize(*this, Data, Kind, Tok.getLocation());
+        }
+
+        if (Tok.is(tok::comma))
+          ConsumeToken();
+        if (Tok.is(tok::r_paren) || Tok.is(tok::annot_pragma_openmp_end))
+          break;
+      }
+      if (!StepFound && !ModifierFound)
+        Diag(ELoc, diag::err_expected_expression);
+    } else {
+      // for OMPC_aligned and OMPC_linear (with OpenMP <= 5.1)
+      ExprResult Tail = ParseAssignmentExpression();
+      Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc,
+                                         /*DiscardedValue*/ false);
+      if (Tail.isUsable())
+        Data.DepModOrTailExpr = Tail.get();
+      else
+        SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
+                  StopBeforeMatch);
+    }
   }
 
   // Parse ')'.
@@ -4787,8 +4863,8 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
     ExitScope();
   return (Kind != OMPC_depend && Kind != OMPC_doacross && Kind != OMPC_map &&
           Vars.empty()) ||
-         (MustHaveTail && !Data.DepModOrTailExpr) || InvalidReductionId ||
-         IsInvalidMapperModifier || InvalidIterator;
+         (MustHaveTail && !Data.DepModOrTailExpr && StepFound) ||
+         InvalidReductionId || IsInvalidMapperModifier || InvalidIterator;
 }
 
 /// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',

diff  --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index eb755e2a0c45408..75f9e152dca9297 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -18049,7 +18049,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
     Res = ActOnOpenMPLinearClause(
         VarList, Data.DepModOrTailExpr, StartLoc, LParenLoc,
         static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
-        ColonLoc, EndLoc);
+        ColonLoc, Data.StepModifierLoc, EndLoc);
     break;
   case OMPC_aligned:
     Res = ActOnOpenMPAlignedClause(VarList, Data.DepModOrTailExpr, StartLoc,
@@ -20134,7 +20134,7 @@ OMPClause *Sema::ActOnOpenMPInReductionClause(
 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
                                      SourceLocation LinLoc) {
   if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
-      LinKind == OMPC_LINEAR_unknown) {
+      LinKind == OMPC_LINEAR_unknown || LinKind == OMPC_LINEAR_step) {
     Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
     return true;
   }
@@ -20186,12 +20186,19 @@ bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
 OMPClause *Sema::ActOnOpenMPLinearClause(
     ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
     SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
-    SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
+    SourceLocation LinLoc, SourceLocation ColonLoc,
+    SourceLocation StepModifierLoc, SourceLocation EndLoc) {
   SmallVector<Expr *, 8> Vars;
   SmallVector<Expr *, 8> Privates;
   SmallVector<Expr *, 8> Inits;
   SmallVector<Decl *, 4> ExprCaptures;
   SmallVector<Expr *, 4> ExprPostUpdates;
+  // OpenMP 5.2 [Section 5.4.6, linear clause]
+  // step-simple-modifier is exclusive, can't be used with 'val', 'uval', or
+  // 'ref'
+  if (LinLoc.isValid() && StepModifierLoc.isInvalid() && Step &&
+      getLangOpts().OpenMP >= 52)
+    Diag(Step->getBeginLoc(), diag::err_omp_step_simple_modifier_exclusive);
   if (CheckOpenMPLinearModifier(LinKind, LinLoc))
     LinKind = OMPC_LINEAR_val;
   for (Expr *RefExpr : VarList) {
@@ -20311,8 +20318,8 @@ OMPClause *Sema::ActOnOpenMPLinearClause(
   }
 
   return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
-                                 ColonLoc, EndLoc, Vars, Privates, Inits,
-                                 StepExpr, CalcStepExpr,
+                                 ColonLoc, StepModifierLoc, EndLoc, Vars,
+                                 Privates, Inits, StepExpr, CalcStepExpr,
                                  buildPreInits(Context, ExprCaptures),
                                  buildPostUpdate(*this, ExprPostUpdates));
 }

diff  --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 094e5efa939f4d1..17ebfe14cecad34 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -1908,16 +1908,14 @@ class TreeTransform {
   ///
   /// By default, performs semantic analysis to build the new OpenMP clause.
   /// Subclasses may override this routine to provide 
diff erent behavior.
-  OMPClause *RebuildOMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step,
-                                    SourceLocation StartLoc,
-                                    SourceLocation LParenLoc,
-                                    OpenMPLinearClauseKind Modifier,
-                                    SourceLocation ModifierLoc,
-                                    SourceLocation ColonLoc,
-                                    SourceLocation EndLoc) {
+  OMPClause *RebuildOMPLinearClause(
+      ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
+      SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier,
+      SourceLocation ModifierLoc, SourceLocation ColonLoc,
+      SourceLocation StepModifierLoc, SourceLocation EndLoc) {
     return getSema().ActOnOpenMPLinearClause(VarList, Step, StartLoc, LParenLoc,
                                              Modifier, ModifierLoc, ColonLoc,
-                                             EndLoc);
+                                             StepModifierLoc, EndLoc);
   }
 
   /// Build a new OpenMP 'aligned' clause.
@@ -10287,7 +10285,8 @@ TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
     return nullptr;
   return getDerived().RebuildOMPLinearClause(
       Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
-      C->getModifierLoc(), C->getColonLoc(), C->getEndLoc());
+      C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
+      C->getEndLoc());
 }
 
 template <typename Derived>

diff  --git a/clang/test/Analysis/cfg-openmp.cpp b/clang/test/Analysis/cfg-openmp.cpp
index 9ab14af4bc75393..d7de34bdaa0ec1d 100644
--- a/clang/test/Analysis/cfg-openmp.cpp
+++ b/clang/test/Analysis/cfg-openmp.cpp
@@ -22,7 +22,7 @@ void target_has_device_addr(int argc) {
 }
 // OMP51-LABEL: void target_s_has_device_addr(int argc)
 void target_s_has_device_addr(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // OMP51-DAG:  [B3]
 // OMP51-DAG: [[#TSB:]]: x
 // OMP51-DAG: [[#TSB+1]]: [B3.[[#TSB]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -35,14 +35,14 @@ void target_s_has_device_addr(int argc) {
 // OMP51-DAG: [[#TS+3]]: fp
 // OMP51-DAG: [[#TS+4]]: rd
 // OMP51-DAG: [[#TS+5]]: lin
-// OMP51-DAG: [[#TS+6]]: step
+// OMP51-DAG: [[#TS+6]]: step_sz
 // OMP51-DAG: [[#TS+7]]: [B1.[[#TS+6]]] (ImplicitCastExpr, LValueToRValue, int)
 // OMP51-DAG: [[#TS+8]]: [B3.[[#TSB+2]]]
 // OMP51-DAG: [[#TS+9]]: [B3.[[#TSB]]]
-// OMP51-DAG: [[#TS+10]]: #pragma omp target simd if(cond) firstprivate(fp) reduction(+: rd) linear(lin: step) has_device_addr(map)
+// OMP51-DAG: [[#TS+10]]: #pragma omp target simd if(cond) firstprivate(fp) reduction(+: rd) linear(lin: step(step_sz)) has_device_addr(map)
 // OMP51-DAG:    for (int i = 0;
 // OMP51-DAG: [B3.[[#TSB+3]]];
-#pragma omp target simd if(cond) firstprivate(fp) reduction(+:rd) linear(lin: step) has_device_addr(map)
+#pragma omp target simd if(cond) firstprivate(fp) reduction(+:rd) linear(lin: step_sz) has_device_addr(map)
   for (int i = 0; i < 10; ++i)
     argc = x;
 }
@@ -129,9 +129,9 @@ void xxx(int argc) {
 // CHECK-NEXT:   3: int fp;
 // CHECK-NEXT:   4: int rd;
 // CHECK-NEXT:   5: int lin;
-// CHECK-NEXT:   6: int step;
+// CHECK-NEXT:   6: int step_sz;
 // CHECK-NEXT:   7: int map;
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-NEXT:   [[#ATOM:]]: x
 // CHECK-NEXT:   [[#ATOM+1]]: [B1.[[#ATOM]]] (ImplicitCastExpr, LValueToRValue, int)
 // CHECK-NEXT:   [[#ATOM+2]]: argc
@@ -294,7 +294,7 @@ void xxx(int argc) {
 
 // CHECK-LABEL:  void dpf(int argc)
 void dpf(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B3]
 // CHECK-DAG:  [[#DPFB:]]: x
 // CHECK-DAG:  [[#DPFB+1]]: [B3.[[#DPFB]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -316,7 +316,7 @@ void dpf(int argc) {
 
 // CHECK-LABEL:  void dpfs(int argc)
 void dpfs(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B3]
 // CHECK-DAG:  [[#DPFSB:]]: x
 // CHECK-DAG:  [[#DPFSB+1]]: [B3.[[#DPFSB]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -338,7 +338,7 @@ void dpfs(int argc) {
 
 // CHECK-LABEL:  void ds(int argc)
 void ds(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B3]
 // CHECK-DAG:  [[#DSB:]]: x
 // CHECK-DAG:  [[#DSB+1]]: [B3.[[#DSB]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -355,7 +355,7 @@ void ds(int argc) {
 
 // CHECK-LABEL:  void for_fn(int argc)
 void for_fn(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B3]
 // CHECK-DAG:  [[#FORB:]]: x
 // CHECK-DAG:  [[#FORB+1]]: [B3.[[#FORB]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -363,19 +363,19 @@ void for_fn(int argc) {
 // CHECK-DAG:  [[#FORB+3]]: [B3.[[#FORB+2]]] = [B3.[[#FORB+1]]]
 // CHECK-DAG:   [B1]
 // CHECK-DAG:  [[#FOR:]]: lin
-// CHECK-DAG:  [[#FOR+1]]: step
+// CHECK-DAG:  [[#FOR+1]]: step_sz
 // CHECK-DAG:  [[#FOR+2]]: [B1.[[#FOR+1]]] (ImplicitCastExpr, LValueToRValue, int)
-// CHECK-DAG:  [[#FOR+3]]: #pragma omp for linear(lin: step)
+// CHECK-DAG:  [[#FOR+3]]: #pragma omp for linear(lin: step(step_sz))
 // CHECK-DAG:    for (int i = 0;
 // CHECK-DAG:        [B3.[[#FORB+3]]];
-#pragma omp for linear(lin : step)
+#pragma omp for linear(lin : step_sz)
   for (int i = 0; i < 10; ++i)
     argc = x;
 }
 
 // CHECK-LABEL:  void fs(int argc)
 void fs(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B3]
 // CHECK-DAG:  [[#FSB:]]: x
 // CHECK-DAG:  [[#FSB+1]]: [B3.[[#FSB]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -383,19 +383,19 @@ void fs(int argc) {
 // CHECK-DAG:  [[#FSB+3]]: [B3.[[#FSB+2]]] = [B3.[[#FSB+1]]]
 // CHECK-DAG:   [B1]
 // CHECK-DAG:  [[#FS:]]: lin
-// CHECK-DAG:  [[#FS+1]]: step
+// CHECK-DAG:  [[#FS+1]]: step_sz
 // CHECK-DAG:  [[#FS+2]]: [B1.[[#FS+1]]] (ImplicitCastExpr, LValueToRValue, int)
-// CHECK-DAG:  [[#FS+3]]: #pragma omp for simd linear(lin: step)
+// CHECK-DAG:  [[#FS+3]]: #pragma omp for simd linear(lin: step(step_sz))
 // CHECK-DAG:    for (int i = 0;
 // CHECK-DAG:        [B3.[[#FSB+3]]];
-#pragma omp for simd linear(lin: step)
+#pragma omp for simd linear(lin: step_sz)
   for (int i = 0; i < 10; ++i)
     argc = x;
 }
 
 // CHECK-LABEL:  void ord(int argc)
 void ord(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B3]
 // CHECK-DAG:  [[#ORDB:]]: x
 // CHECK-DAG:  [[#ORDB+1]]: [B3.[[#ORDB]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -416,7 +416,7 @@ void ord(int argc) {
 
 // CHECK-LABEL:  void pf(int argc)
 void pf(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B3]
 // CHECK-DAG:  [[#PFB:]]: x
 // CHECK-DAG:  [[#PFB+1]]: [B3.[[#PFB]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -429,19 +429,19 @@ void pf(int argc) {
 // CHECK-DAG:  [[#PF+3]]: fp
 // CHECK-DAG:  [[#PF+4]]: rd
 // CHECK-DAG:  [[#PF+5]]: lin
-// CHECK-DAG:  [[#PF+6]]: step
+// CHECK-DAG:  [[#PF+6]]: step_sz
 // CHECK-DAG:  [[#PF+7]]: [B1.[[#PF+6]]] (ImplicitCastExpr, LValueToRValue, int)
-// CHECK-DAG:  [[#PF+8]]: #pragma omp parallel for if(cond) firstprivate(fp) reduction(&: rd) linear(lin: step)
+// CHECK-DAG:  [[#PF+8]]: #pragma omp parallel for if(cond) firstprivate(fp) reduction(&: rd) linear(lin: step(step_sz))
 // CHECK-DAG:    for (int i = 0;
 // CHECK-DAG:        [B3.[[#PFB+3]]];
-#pragma omp parallel for if(cond) firstprivate(fp) reduction(&:rd) linear(lin: step)
+#pragma omp parallel for if(cond) firstprivate(fp) reduction(&:rd) linear(lin: step_sz)
   for (int i = 0; i < 10; ++i)
     argc = x;
 }
 
 // CHECK-LABEL:  void pfs(int argc)
 void pfs(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B3]
 // CHECK-DAG:  [[#PFSB:]]: x
 // CHECK-DAG:  [[#PFSB+1]]: [B3.[[#PFSB]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -454,19 +454,19 @@ void pfs(int argc) {
 // CHECK-DAG:  [[#PFS+3]]: fp
 // CHECK-DAG:  [[#PFS+4]]: rd
 // CHECK-DAG:  [[#PFS+5]]: lin
-// CHECK-DAG:  [[#PFS+6]]: step
+// CHECK-DAG:  [[#PFS+6]]: step_sz
 // CHECK-DAG:  [[#PFS+7]]: [B1.[[#PFS+6]]] (ImplicitCastExpr, LValueToRValue, int)
-// CHECK-DAG:  [[#PFS+8]]: #pragma omp parallel for simd if(cond) firstprivate(fp) reduction(|: rd) linear(lin: step)
+// CHECK-DAG:  [[#PFS+8]]: #pragma omp parallel for simd if(cond) firstprivate(fp) reduction(|: rd) linear(lin: step(step_sz))
 // CHECK-DAG:    for (int i = 0;
 // CHECK-DAG:        [B3.[[#PFSB+3]]];
-#pragma omp parallel for simd if(cond) firstprivate(fp) reduction(|:rd) linear(lin: step)
+#pragma omp parallel for simd if(cond) firstprivate(fp) reduction(|:rd) linear(lin: step_sz)
   for (int i = 0; i < 10; ++i)
     argc = x;
 }
 
 // CHECK-LABEL:  void simd(int argc)
 void simd(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B3]
 // CHECK-DAG:  [[#SIMDB:]]: x
 // CHECK-DAG:  [[#SIMDB+1]]: [B3.[[#SIMDB]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -474,19 +474,19 @@ void simd(int argc) {
 // CHECK-DAG:  [[#SIMDB+3]]: [B3.[[#SIMDB+2]]] = [B3.[[#SIMDB+1]]]
 // CHECK-DAG:   [B1]
 // CHECK-DAG:  [[#SIMD:]]: lin
-// CHECK-DAG:  [[#SIMD+1]]: step
+// CHECK-DAG:  [[#SIMD+1]]: step_sz
 // CHECK-DAG:  [[#SIMD+2]]: [B1.[[#SIMD+1]]] (ImplicitCastExpr, LValueToRValue, int)
-// CHECK-DAG:  [[#SIMD+3]]: #pragma omp simd linear(lin: step)
+// CHECK-DAG:  [[#SIMD+3]]: #pragma omp simd linear(lin: step(step_sz))
 // CHECK-DAG:    for (int i = 0;
 // CHECK-DAG:        [B3.[[#SIMDB+3]]];
-#pragma omp simd linear(lin: step)
+#pragma omp simd linear(lin: step_sz)
   for (int i = 0; i < 10; ++i)
     argc = x;
 }
 
 // CHECK-LABEL:  void tpf(int argc)
 void tpf(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B3]
 // CHECK-DAG:  [[#TPFB:]]: x
 // CHECK-DAG:  [[#TPFB+1]]: [B3.[[#TPFB]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -499,22 +499,22 @@ void tpf(int argc) {
 // CHECK-DAG:  [[#TPF+3]]: fp
 // CHECK-DAG:  [[#TPF+4]]: rd
 // CHECK-DAG:  [[#TPF+5]]: lin
-// CHECK-DAG:  [[#TPF+6]]: step
+// CHECK-DAG:  [[#TPF+6]]: step_sz
 // CHECK-DAG:  [[#TPF+7]]: [B1.[[#TPF+6]]] (ImplicitCastExpr, LValueToRValue, int)
 // CHECK-DAG:  [[#TPF+8]]: map
 // CHECK-DAG:  [[#TPF+9]]: [B3.[[#TPFB+2]]]
 // CHECK-DAG:  [[#TPF+10]]: [B3.[[#TPFB]]]
-// CHECK-DAG:  [[#TPF+11]]: #pragma omp target parallel for if(parallel: cond) firstprivate(fp) reduction(max: rd) linear(lin: step) map(tofrom: map)
+// CHECK-DAG:  [[#TPF+11]]: #pragma omp target parallel for if(parallel: cond) firstprivate(fp) reduction(max: rd) linear(lin: step(step_sz)) map(tofrom: map)
 // CHECK-DAG:    for (int i = 0;
 // CHECK-DAG:        [B3.[[#TPFB+3]]];
-#pragma omp target parallel for if(parallel:cond) firstprivate(fp) reduction(max:rd) linear(lin: step) map(map)
+#pragma omp target parallel for if(parallel:cond) firstprivate(fp) reduction(max:rd) linear(lin: step_sz) map(map)
   for (int i = 0; i < 10; ++i)
     argc = x;
 }
 
 // CHECK-LABEL:  void tpfs(int argc)
 void tpfs(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B3]
 // CHECK-DAG:  [[#TPFSB:]]: x
 // CHECK-DAG:  [[#TPFSB+1]]: [B3.[[#TPFSB]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -527,22 +527,22 @@ void tpfs(int argc) {
 // CHECK-DAG:  [[#TPFS+3]]: fp
 // CHECK-DAG:  [[#TPFS+4]]: rd
 // CHECK-DAG:  [[#TPFS+5]]: lin
-// CHECK-DAG:  [[#TPFS+6]]: step
+// CHECK-DAG:  [[#TPFS+6]]: step_sz
 // CHECK-DAG:  [[#TPFS+7]]: [B1.[[#TPFS+6]]] (ImplicitCastExpr, LValueToRValue, int)
 // CHECK-DAG:  [[#TPFS+8]]: map
 // CHECK-DAG:  [[#TPFS+9]]: [B3.[[#TPFSB+2]]]
 // CHECK-DAG:  [[#TPFS+10]]: [B3.[[#TPFSB]]]
-// CHECK-DAG:  [[#TPFS+11]]: #pragma omp target parallel for simd if(target: cond) firstprivate(fp) reduction(*: rd) linear(lin: step) map(tofrom: map)
+// CHECK-DAG:  [[#TPFS+11]]: #pragma omp target parallel for simd if(target: cond) firstprivate(fp) reduction(*: rd) linear(lin: step(step_sz)) map(tofrom: map)
 // CHECK-DAG:    for (int i = 0;
 // CHECK-DAG:        [B3.[[#TPFSB+3]]];
-#pragma omp target parallel for simd if(target:cond) firstprivate(fp) reduction(*:rd) linear(lin: step) map(tofrom:map)
+#pragma omp target parallel for simd if(target:cond) firstprivate(fp) reduction(*:rd) linear(lin: step_sz) map(tofrom:map)
   for (int i = 0; i < 10; ++i)
     argc = x;
 }
 
 // CHECK-LABEL:  void ts(int argc)
 void ts(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B3]
 // CHECK-DAG:  [[#TSB:]]: x
 // CHECK-DAG:  [[#TSB+1]]: [B3.[[#TSB]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -555,21 +555,21 @@ void ts(int argc) {
 // CHECK-DAG:  [[#TS+3]]: fp
 // CHECK-DAG:  [[#TS+4]]: rd
 // CHECK-DAG:  [[#TS+5]]: lin
-// CHECK-DAG:  [[#TS+6]]: step
+// CHECK-DAG:  [[#TS+6]]: step_sz
 // CHECK-DAG:  [[#TS+7]]: [B1.[[#TS+6]]] (ImplicitCastExpr, LValueToRValue, int)
 // CHECK-DAG:  [[#TS+8]]: [B3.[[#TSB+2]]]
 // CHECK-DAG:  [[#TS+9]]: [B3.[[#TSB]]]
-// CHECK-DAG:  [[#TS+10]]: #pragma omp target simd if(cond) firstprivate(fp) reduction(+: rd) linear(lin: step) map(alloc: map)
+// CHECK-DAG:  [[#TS+10]]: #pragma omp target simd if(cond) firstprivate(fp) reduction(+: rd) linear(lin: step(step_sz)) map(alloc: map)
 // CHECK-DAG:    for (int i = 0;
 // CHECK-DAG:        [B3.[[#TSB+3]]];
-#pragma omp target simd if(cond) firstprivate(fp) reduction(+:rd) linear(lin: step) map(alloc:map)
+#pragma omp target simd if(cond) firstprivate(fp) reduction(+:rd) linear(lin: step_sz) map(alloc:map)
   for (int i = 0; i < 10; ++i)
     argc = x;
 }
 
 // CHECK-LABEL:  void ttd(int argc)
 void ttd(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B3]
 // CHECK-DAG:  [[#TTDB:]]: x
 // CHECK-DAG:  [[#TTDB+1]]: [B3.[[#TTDB]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -593,7 +593,7 @@ void ttd(int argc) {
 
 // CHECK-LABEL:  void ttdpf(int argc)
 void ttdpf(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B3]
 // CHECK-DAG:  [[#TTDPFB:]]: x
 // CHECK-DAG:  [[#TTDPFB+1]]: [B3.[[#TTDPFB]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -617,7 +617,7 @@ void ttdpf(int argc) {
 
 // CHECK-LABEL:  void ttdpfs(int argc)
 void ttdpfs(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B3]
 // CHECK-DAG:  [[#TTDPFSB:]]: x
 // CHECK-DAG:  [[#TTDPFSB+1]]: [B3.[[#TTDPFSB]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -641,7 +641,7 @@ void ttdpfs(int argc) {
 
 // CHECK-LABEL:  void ttds(int argc)
 void ttds(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B3]
 // CHECK-DAG:  [[#TTDSB:]]: x
 // CHECK-DAG:  [[#TTDSB+1]]: [B3.[[#TTDSB]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -666,7 +666,7 @@ void ttds(int argc) {
 
 // CHECK-LABEL:  void tl(int argc)
 void tl(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B3]
 // CHECK-DAG:  [[#TLB:]]: x
 // CHECK-DAG:  [[#TLB+1]]: [B3.[[#TLB]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -690,7 +690,7 @@ void tl(int argc) {
 
 // CHECK-LABEL:  void maskedtaskloop(int argc)
 void maskedtaskloop(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B3]
 // CHECK-DAG:  [[#MTLB:]]: x
 // CHECK-DAG:  [[#MTLB+1]]: [B3.[[#MTLB]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -714,7 +714,7 @@ void maskedtaskloop(int argc) {
 
 // CHECK-LABEL:  void parallelmaskedtaskloop(int argc)
 void parallelmaskedtaskloop(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B3]
 // CHECK-DAG:  [[#PMTLB:]]: x
 // CHECK-DAG:  [[#PMTLB+1]]: [B3.[[#PMTLB]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -738,7 +738,7 @@ void parallelmaskedtaskloop(int argc) {
 
 // CHECK-LABEL:  void parallelmaskedtasksimdloop(int argc)
 void parallelmaskedtasksimdloop(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B3]
 // CHECK-DAG:  [[#PMTLSB:]]: x
 // CHECK-DAG:  [[#PMTLSB+1]]: [B3.[[#PMTLSB]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -762,7 +762,7 @@ void parallelmaskedtasksimdloop(int argc) {
 
 // CHECK-LABEL:  void tls(int argc)
 void tls(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B3]
 // CHECK-DAG:  [[#TLSB:]]: x
 // CHECK-DAG:  [[#TLSB+1]]: [B3.[[#TLSB]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -775,21 +775,21 @@ void tls(int argc) {
 // CHECK-DAG:  [[#TLS+3]]: fp
 // CHECK-DAG:  [[#TLS+4]]: rd
 // CHECK-DAG:  [[#TLS+5]]: lin
-// CHECK-DAG:  [[#TLS+6]]: step
+// CHECK-DAG:  [[#TLS+6]]: step_sz
 // CHECK-DAG:  [[#TLS+7]]: [B1.[[#TLS+6]]] (ImplicitCastExpr, LValueToRValue, int)
 // CHECK-DAG:  [[#TLS+8]]: [B3.[[#TLSB+2]]]
 // CHECK-DAG:  [[#TLS+9]]: [B3.[[#TLSB]]]
-// CHECK-DAG:  [[#TLS+10]]: #pragma omp taskloop simd if(cond) firstprivate(fp) reduction(+: rd) linear(lin: step)
+// CHECK-DAG:  [[#TLS+10]]: #pragma omp taskloop simd if(cond) firstprivate(fp) reduction(+: rd) linear(lin: step(step_sz))
 // CHECK-DAG:    for (int i = 0;
 // CHECK-DAG:        [B3.[[#TLSB+3]]];
-#pragma omp taskloop simd if(cond) firstprivate(fp) reduction(+:rd) linear(lin: step)
+#pragma omp taskloop simd if(cond) firstprivate(fp) reduction(+:rd) linear(lin: step_sz)
   for (int i = 0; i < 10; ++i)
     argc = x;
 }
 
 // CHECK-LABEL:  void maskedtaskloopsimd(int argc)
 void maskedtaskloopsimd(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B3]
 // CHECK-DAG:  [[#MTLSB:]]: x
 // CHECK-DAG:  [[#MTLSB+1]]: [B3.[[#MTLSB]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -802,21 +802,21 @@ void maskedtaskloopsimd(int argc) {
 // CHECK-DAG:  [[#MTLS+3]]: fp
 // CHECK-DAG:  [[#MTLS+4]]: rd
 // CHECK-DAG:  [[#MTLS+5]]: lin
-// CHECK-DAG:  [[#MTLS+6]]: step
+// CHECK-DAG:  [[#MTLS+6]]: step_sz
 // CHECK-DAG:  [[#MTLS+7]]: [B1.[[#MTLS+6]]] (ImplicitCastExpr, LValueToRValue, int)
 // CHECK-DAG:  [[#MTLS+8]]: [B3.[[#MTLSB+2]]]
 // CHECK-DAG:  [[#MTLS+9]]: [B3.[[#MTLSB]]]
-// CHECK-DAG:  [[#MTLS+10]]: #pragma omp masked taskloop simd if(cond) firstprivate(fp) reduction(+: rd) linear(lin: step)
+// CHECK-DAG:  [[#MTLS+10]]: #pragma omp masked taskloop simd if(cond) firstprivate(fp) reduction(+: rd) linear(lin: step(step_sz))
 // CHECK-DAG:    for (int i = 0;
 // CHECK-DAG:        [B3.[[#MTLSB+3]]];
-#pragma omp masked taskloop simd if(cond) firstprivate(fp) reduction(+:rd) linear(lin: step)
+#pragma omp masked taskloop simd if(cond) firstprivate(fp) reduction(+:rd) linear(lin: step_sz)
   for (int i = 0; i < 10; ++i)
     argc = x;
 }
 
 // CHECK-LABEL:  void tdpf(int argc)
 void tdpf(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B1]
 // CHECK-DAG:  [[#TDPF:]]: [B1.{{.+}}]
 // CHECK-DAG:  [[#TDPF+1]]: [B1.[[#TDPF+6]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -845,7 +845,7 @@ void tdpf(int argc) {
 
 // CHECK-LABEL:  void tdpfs(int argc)
 void tdpfs(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B1]
 // CHECK-DAG:  [[#TDPFS:]]: [B1.{{.+}}]
 // CHECK-DAG:  [[#TDPFS+1]]: [B1.[[#TDPFS+6]]] (ImplicitCastExpr, LValueToRValue, int)
@@ -874,7 +874,7 @@ void tdpfs(int argc) {
 
 // CHECK-LABEL:  void tds(int argc)
 void tds(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B1]
 // CHECK-DAG:  [[#TDS:]]: #pragma omp teams distribute simd firstprivate(fp) reduction(+: rd)
 // CHECK-DAG:  [[#TDS-2]]: [B1.[[#TDS+1]]]
@@ -899,7 +899,7 @@ void tds(int argc) {
 
 // CHECK-LABEL:  void teamsloop(int argc)
 void teamsloop(int argc) {
-  int x, cond, fp, rd, lin, step, map;
+  int x, cond, fp, rd, lin, step_sz, map;
 // CHECK-DAG:   [B1]
 // CHECK-DAG:  [[#TDS:]]: #pragma omp teams loop firstprivate(fp) reduction(+: rd)
 // CHECK-DAG:  [[#TDS-2]]: [B1.[[#TDS+1]]]

diff  --git a/clang/test/OpenMP/declare_simd_messages.cpp b/clang/test/OpenMP/declare_simd_messages.cpp
index 60515965ce3d092..dd24322694b69fd 100644
--- a/clang/test/OpenMP/declare_simd_messages.cpp
+++ b/clang/test/OpenMP/declare_simd_messages.cpp
@@ -122,11 +122,12 @@ void test() {
 #pragma omp declare simd aligned(
 // expected-error at +1 {{expected expression}}
 #pragma omp declare simd aligned()
+// expected-error at +4 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
 // expected-note at +3 {{to match this '('}}
 // expected-error at +2 {{expected ')'}}
 // expected-error at +1 {{expected expression}}
 #pragma omp declare simd aligned(a:
-// expected-error at +1 {{expected expression}}
+// expected-error at +1 {{expected expression}} expected-error at +1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
 #pragma omp declare simd aligned(a:)
 // expected-warning at +2 {{extra tokens at the end of '#pragma omp declare simd' are ignored}}
 // expected-error at +1 {{expected '(' after 'aligned'}}
@@ -205,6 +206,8 @@ void test() {
 // expected-error at +1 {{expected one of 'ref', val' or 'uval' modifiers}} expected-warning at +1 {{extra tokens at the end of '#pragma omp declare simd' are ignored}}
 #pragma omp declare simd linear(uref(b)) allocate(b)
 #pragma omp declare simd linear(ref(c))
+// expected-note at +2 {{'a' declared here}}
+// expected-note at +1 {{'a' declared here}}
 void bar(int a, int *b, float &c);
 
 template <class T>

diff  --git a/clang/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp
index 48809c07ffc3929..94ba8494d7126eb 100644
--- a/clang/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp
+++ b/clang/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp
@@ -165,9 +165,9 @@ int main(int argc, char **argv) {
   for (i = 0; i < 100; i++)
     for (int j = 0; j < 200; j++)
       a += h + x[j];
-  // OMP45: #pragma omp distribute parallel for simd aligned(x: 8) linear(i: 2) safelen(8) simdlen(8)
-  // OMP50: #pragma omp distribute parallel for simd aligned(x: 8) linear(i: 2) safelen(8) simdlen(8) if(simd: argc) nontemporal(argc,c,d) order(concurrent)
-  // OMP51: #pragma omp distribute parallel for simd aligned(x: 8) linear(i: 2) safelen(8) simdlen(8) if(simd: argc) nontemporal(argc,c,d) order(unconstrained: concurrent)
+  // OMP45: #pragma omp distribute parallel for simd aligned(x: 8) linear(i: step(2)) safelen(8) simdlen(8)
+  // OMP50: #pragma omp distribute parallel for simd aligned(x: 8) linear(i: step(2)) safelen(8) simdlen(8) if(simd: argc) nontemporal(argc,c,d) order(concurrent)
+  // OMP51: #pragma omp distribute parallel for simd aligned(x: 8) linear(i: step(2)) safelen(8) simdlen(8) if(simd: argc) nontemporal(argc,c,d) order(unconstrained: concurrent)
   // CHECK-NEXT: for (i = 0; i < 100; i++)
   // CHECK-NEXT: for (int j = 0; j < 200; j++)
   // CHECK-NEXT: a += h + x[j];

diff  --git a/clang/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp
index cdfb9bc605eec1d..be05533d43f9be4 100644
--- a/clang/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp
@@ -1,6 +1,8 @@
 // RUN: %clang_cc1 -verify -fopenmp %s -Wno-openmp-mapping -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -DOMP52 %s -Wno-openmp-mapping -Wuninitialized
 
 // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wno-openmp-mapping -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 -DOMP52 %s -Wno-openmp-mapping -Wuninitialized
 
 extern int omp_default_mem_alloc;
 
@@ -333,6 +335,33 @@ int main(int argc, char **argv) {
     #pragma omp teams
     #pragma omp distribute parallel for simd linear(i : 4)
       for (i = 0; i < argc; ++i) { ++i; i += 4; }
+
+#ifdef OMP52
+    #pragma omp target
+    #pragma omp teams
+    #pragma omp distribute parallel for simd linear(i: step() //omp52-error 2 {{expected expression}} omp52-error{{expected ')'}} omp52-note{{to match this '('}}
+      for (i = 0; i < argc; ++i) ++i;
+    #pragma omp target
+    #pragma omp teams
+    #pragma omp distribute parallel for simd linear(i: step(1), step(2)) // omp52-error {{multiple 'step size' found in linear clause}}
+      for (i = 0; i < argc; ++i) ++i;
+    #pragma omp target
+    #pragma omp teams
+    #pragma omp distribute parallel for simd linear(i: val, val) // omp52-error {{multiple 'linear modifier' found in linear clause}}
+      for (i = 0; i < argc; ++i) ++i;
+    #pragma omp target
+    #pragma omp teams
+    #pragma omp distribute parallel for simd linear(i: step()) // omp52-error 2 {{expected expression}}
+      for (i = 0; i < argc; ++i) ++i;
+    #pragma omp target
+    #pragma omp teams
+    #pragma omp distribute parallel for simd linear(i: pval) // omp52-error {{use of undeclared identifier 'pval'}} 
+      for (i = 0; i < argc; ++i) ++i;
+    #pragma omp target
+    #pragma omp teams
+    #pragma omp distribute parallel for simd linear(i: val, step(2 // omp52-error {{expected ')' or ',' after 'step expression'}} omp52-error 2 {{expected ')'}}  omp52-note 2 {{to match this '('}}
+      for (i = 0; i < argc; ++i) ++i;
+#endif
   }
 
   foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}

diff  --git a/clang/test/OpenMP/distribute_simd_ast_print.cpp b/clang/test/OpenMP/distribute_simd_ast_print.cpp
index a39a1af9267f272..aed9d6376ef5880 100644
--- a/clang/test/OpenMP/distribute_simd_ast_print.cpp
+++ b/clang/test/OpenMP/distribute_simd_ast_print.cpp
@@ -7,6 +7,9 @@
 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -ast-print %s -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51
 // RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51
 // RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -ast-print %s -Wno-openmp-mapping -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP52
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -Wno-openmp-mapping -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=45 -ast-print %s -Wno-openmp-mapping | FileCheck %s --check-prefix=CHECK --check-prefix=OMP45
 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s
@@ -18,6 +21,10 @@
 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=51 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51
 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=51 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51
 // expected-no-diagnostics
+// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -ast-print %s -Wno-openmp-mapping -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP52
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -Wno-openmp-mapping -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
+// expected-no-diagnostics
 
 #ifndef HEADER
 #define HEADER
@@ -147,6 +154,7 @@ int main(int argc, char **argv) {
 // OMP45: #pragma omp distribute simd private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) reduction(+: h) dist_schedule(static, b)
 // OMP50: #pragma omp distribute simd private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) reduction(+: h) dist_schedule(static, b) if(simd: argc)
 // OMP51: #pragma omp distribute simd private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) reduction(+: h) dist_schedule(static, b)
+// OMP52: #pragma omp distribute simd private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) reduction(+: h) dist_schedule(static, b)
 // CHECK-NEXT: for (int i = 0; i < 10; ++i)
 // CHECK-NEXT: for (int j = 0; j < 10; ++j)
 // CHECK-NEXT: a++;
@@ -154,7 +162,9 @@ int main(int argc, char **argv) {
   int i;
 #pragma omp target
 #pragma omp teams
-#ifdef OMP51
+#ifdef OMP52
+#pragma omp distribute simd aligned(x:8) linear(i: step(2)) safelen(8) simdlen(8) if(argc) nontemporal(argc, c, d) order(reproducible:concurrent)
+#elif OMP51
 #pragma omp distribute simd aligned(x:8) linear(i:2) safelen(8) simdlen(8) if(argc) nontemporal(argc, c, d) order(reproducible:concurrent)
 #elif OMP5
 #pragma omp distribute simd aligned(x:8) linear(i:2) safelen(8) simdlen(8) if(argc) nontemporal(argc, c, d) order(concurrent)
@@ -164,9 +174,10 @@ int main(int argc, char **argv) {
   for (i = 0; i < 100; i++)
     for (int j = 0; j < 200; j++)
       a += h + x[j];
-// OMP45: #pragma omp distribute simd aligned(x: 8) linear(i: 2) safelen(8) simdlen(8)
-// OMP50: #pragma omp distribute simd aligned(x: 8) linear(i: 2) safelen(8) simdlen(8) if(argc) nontemporal(argc,c,d) order(concurrent)
-// OMP51: #pragma omp distribute simd aligned(x: 8) linear(i: 2) safelen(8) simdlen(8) if(argc) nontemporal(argc,c,d) order(reproducible: concurrent)
+// OMP45: #pragma omp distribute simd aligned(x: 8) linear(i: step(2)) safelen(8) simdlen(8)
+// OMP50: #pragma omp distribute simd aligned(x: 8) linear(i: step(2)) safelen(8) simdlen(8) if(argc) nontemporal(argc,c,d) order(concurrent)
+// OMP51: #pragma omp distribute simd aligned(x: 8) linear(i: step(2)) safelen(8) simdlen(8) if(argc) nontemporal(argc,c,d) order(reproducible: concurrent)
+// OMP52: #pragma omp distribute simd aligned(x: 8) linear(i: step(2)) safelen(8) simdlen(8) if(argc) nontemporal(argc,c,d) order(reproducible: concurrent)
 // CHECK-NEXT: for (i = 0; i < 100; i++)
 // CHECK-NEXT: for (int j = 0; j < 200; j++)
 // CHECK-NEXT: a += h + x[j];

diff  --git a/clang/test/OpenMP/distribute_simd_linear_messages.cpp b/clang/test/OpenMP/distribute_simd_linear_messages.cpp
index 1ba4c5ceeb734bc..a56fd636b6f1aaa 100644
--- a/clang/test/OpenMP/distribute_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/distribute_simd_linear_messages.cpp
@@ -1,6 +1,8 @@
 // RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -DOMP52 %s -Wno-openmp-mapping -Wuninitialized
 
 // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 -DOMP52 %s -Wno-openmp-mapping -Wuninitialized
 
 extern int omp_default_mem_alloc;
 
@@ -322,6 +324,33 @@ int main(int argc, char **argv) {
     #pragma omp teams
     #pragma omp distribute simd linear(k : 4)
       for (k = 0; k < argc; k+=4) { }
+
+#ifdef OMP52
+    #pragma omp target
+    #pragma omp teams
+    #pragma omp distribute simd linear(k: step() //omp52-error 2 {{expected expression}} omp52-error{{expected ')'}} omp52-note{{to match this '('}}
+      for (k = 0; k < argc; ++k) ++k;
+    #pragma omp target
+    #pragma omp teams
+    #pragma omp distribute simd linear(k: step(1), step(2)) // omp52-error {{multiple 'step size' found in linear clause}}
+      for (k = 0; k < argc; ++k) ++k;
+    #pragma omp target
+    #pragma omp teams
+    #pragma omp distribute simd linear(k: val, val) // omp52-error {{multiple 'linear modifier' found in linear clause}}
+      for (k = 0; k < argc; ++k) ++k;
+    #pragma omp target
+    #pragma omp teams
+    #pragma omp distribute simd linear(k: step()) // omp52-error 2 {{expected expression}}
+      for (k = 0; k < argc; ++k) ++k;
+    #pragma omp target
+    #pragma omp teams
+    #pragma omp distribute simd linear(k: pval) // omp52-error {{use of undeclared identifier 'pval'}}
+      for (k = 0; k < argc; ++k) ++k;
+    #pragma omp target
+    #pragma omp teams
+    #pragma omp distribute simd linear(i: val, step(2 // omp52-error {{expected ')' or ',' after 'step expression'}} omp52-error 2 {{expected ')'}}  omp52-note 2 {{to match this '('}}
+      for (i = 0; i < argc; ++i) ++i;
+#endif
   }
 
   foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}

diff  --git a/clang/test/OpenMP/for_ast_print.cpp b/clang/test/OpenMP/for_ast_print.cpp
index 6ac945758aaa6a7..0a3c694ba162dab 100644
--- a/clang/test/OpenMP/for_ast_print.cpp
+++ b/clang/test/OpenMP/for_ast_print.cpp
@@ -4,6 +4,9 @@
 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -ast-print %s -Wsign-conversion -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51
 // RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51
 // RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -ast-print %s -Wsign-conversion -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP52
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s -Wsign-conversion | FileCheck %s --check-prefix=CHECK --check-prefix=OMP50
 // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s
@@ -11,6 +14,9 @@
 // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 -ast-print %s -Wsign-conversion -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51
 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=51 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51
 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=51 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51
+// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -ast-print %s -Wsign-conversion -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP52
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
 // expected-no-diagnostics
 
 #ifndef HEADER
@@ -62,13 +68,13 @@ class S7 : public T {
 
 // CHECK: #pragma omp for private(this->a) private(this->a) private(T::a)
 // CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a) lastprivate(T::a)
-// CHECK: #pragma omp for linear(val(this->c))
+// CHECK: #pragma omp for linear(this->c: val)
 // CHECK: #pragma omp for private(this->a) private(this->a)
 // CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a)
-// CHECK: #pragma omp for linear(uval(this->b))
+// CHECK: #pragma omp for linear(this->b: uval)
 // CHECK: #pragma omp for private(this->a) private(this->a) private(this->S::a)
 // CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a) lastprivate(this->S::a)
-// CHECK: #pragma omp for linear(val(this->c))
+// CHECK: #pragma omp for linear(this->c: val)
 
 class S8 : public S7<S> {
   S8() {}
@@ -101,7 +107,7 @@ class S8 : public S7<S> {
 
 // CHECK: #pragma omp for private(this->a) private(this->a) private(this->S7<S>::a)
 // CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a) lastprivate(this->S7<S>::a)
-// CHECK: #pragma omp for linear(ref(this->S7<S>::d))
+// CHECK: #pragma omp for linear(this->S7<S>::d: ref)
 // CHECK: #pragma omp for private(this->a) private(this->a)
 // CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a)
 // CHECK: #pragma omp for linear(this->c)
@@ -227,25 +233,32 @@ int main(int argc, char **argv) {
   float arr[20];
   static int a;
 // CHECK: static int a;
-#ifdef OMP51
+#ifdef OMP52
+#pragma omp for schedule(guided, argc) reduction(+:argv[0][:1]) order(unconstrained:concurrent)
+#elif OMP51
 #pragma omp for schedule(guided, argc) reduction(+:argv[0][:1]) order(unconstrained:concurrent)
 #else
 #pragma omp for schedule(guided, argc) reduction(+:argv[0][:1]) order(concurrent)
 #endif // OMP51
   // OMP50: #pragma omp for schedule(guided, argc) reduction(+: argv[0][:1]) order(concurrent)
   // OMP51: #pragma omp for schedule(guided, argc) reduction(+: argv[0][:1]) order(unconstrained: concurrent)
+  // OMP52: #pragma omp for schedule(guided, argc) reduction(+: argv[0][:1]) order(unconstrained: concurrent)
   for (int i = argc; i < c; ++i)
     a = 2;
 // CHECK-NEXT: for (int i = argc; i < c; ++i)
 // CHECK-NEXT: a = 2;
 #pragma omp parallel
+#ifdef OMP52 
+#pragma omp for private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(3) schedule(auto) ordered nowait linear(g: step(-1)) reduction(task, +:e)
+#else
 #pragma omp for private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(3) schedule(auto) ordered nowait linear(g:-1) reduction(task, +:e)
+#endif
   for (int i = 0; i < 10; ++i)
     for (int j = 0; j < 10; ++j)
       for (auto x : arr)
         foo(), (void)x;
   // CHECK-NEXT: #pragma omp parallel
-  // CHECK-NEXT: #pragma omp for private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(3) schedule(auto) ordered nowait linear(g: -1) reduction(task, +: e)
+  // CHECK-NEXT: #pragma omp for private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(3) schedule(auto) ordered nowait linear(g: step(-1)) reduction(task, +: e)
   // CHECK-NEXT: for (int i = 0; i < 10; ++i)
   // CHECK-NEXT: for (int j = 0; j < 10; ++j)
   // CHECK-NEXT: for (auto x : arr)

diff  --git a/clang/test/OpenMP/for_linear_messages.cpp b/clang/test/OpenMP/for_linear_messages.cpp
index 363bbdbbe9dc3c6..03c5c763d7b5c1d 100644
--- a/clang/test/OpenMP/for_linear_messages.cpp
+++ b/clang/test/OpenMP/for_linear_messages.cpp
@@ -1,12 +1,14 @@
 // RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 extern int omp_default_mem_alloc;
 
 void xxx(int argc) {
-  int i, lin, step; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step' to silence this warning}}
-#pragma omp for linear(lin : step) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step' is uninitialized when used here}}
+  int i, lin, step_sz; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step_sz' to silence this warning}}
+#pragma omp for linear(lin : step_sz) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step_sz' is uninitialized when used here}}
   for (i = 0; i < 10; ++i)
     ;
 }
@@ -213,15 +215,39 @@ int main(int argc, char **argv) {
     int i;
     #pragma omp for linear(i)
     for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+    #pragma omp for linear(i : step(4))
+#else
     #pragma omp for linear(i : 4)
+#endif
     for (int k = 0; k < argc; ++k) { ++k; i += 4; }
   }
+#ifdef OMP52
+  #pragma omp for linear(j: step() //omp52-error 2 {{expected expression}} omp52-error{{expected ')'}} omp52-note{{to match this '('}}
+#else
   #pragma omp for linear(j)
+#endif
   for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+  #pragma omp for linear(i: step(1), val)
+#else
   #pragma omp for linear(i)
+#endif
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp for linear(i) ordered(1) // expected-error {{'linear' clause cannot be specified along with 'ordered' clause with a parameter}}
   for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+  #pragma omp for linear(j: step()) // omp52-error 2 {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp for linear(j: step(1), step(2)) // omp52-error {{multiple 'step size' found in linear clause}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp for linear(j: val, val) // omp52-error {{multiple 'linear modifier' found in linear clause}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp for linear(j: pval) // omp52-error{{use of undeclared identifier 'pval'}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp for linear(i: val, step(2 // omp52-error 3 {{expected ')'}} omp52-note 2 {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+#endif
 
   foomain<int,char>(argc,argv); // expected-note {{n instantiation of function template specialization 'foomain<int, char>' requested here}}
   return 0;

diff  --git a/clang/test/OpenMP/for_simd_ast_print.cpp b/clang/test/OpenMP/for_simd_ast_print.cpp
index 137a34a2877033e..0e8c13f7cc8fe2b 100644
--- a/clang/test/OpenMP/for_simd_ast_print.cpp
+++ b/clang/test/OpenMP/for_simd_ast_print.cpp
@@ -6,7 +6,10 @@
 // RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -DOMP5 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP50
 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -ast-print %s -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51
 // RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51
-// RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -ast-print %s -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP52
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=45 -ast-print %s | FileCheck %s --check-prefix=CHECK --check-prefix=OMP45
 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s
@@ -18,6 +21,10 @@
 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=51 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51
 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=51 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51
 // expected-no-diagnostics
+// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -ast-print %s -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP52
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
+// expected-no-diagnostics
 
 #ifndef HEADER
 #define HEADER
@@ -102,16 +109,19 @@ template<class T> struct S {
 // CHECK: T res;
 // CHECK: T val;
 // CHECK: T lin = 0;
-#ifdef OMP51
+#ifdef OMP52
+    #pragma omp for simd private(val)  safelen(7) linear(lin : step(-5)) lastprivate(res) simdlen(5) allocate(res) if(res) nontemporal(res, val, lin) order(reproducible:concurrent)
+#elif OMP51
     #pragma omp for simd private(val)  safelen(7) linear(lin : -5) lastprivate(res) simdlen(5) allocate(res) if(res) nontemporal(res, val, lin) order(reproducible:concurrent)
 #elif OMP5
     #pragma omp for simd private(val)  safelen(7) linear(lin : -5) lastprivate(res) simdlen(5) allocate(res) if(res) nontemporal(res, val, lin) order(concurrent)
 #else
     #pragma omp for simd private(val)  safelen(7) linear(lin : -5) lastprivate(res) simdlen(5) allocate(res)
 #endif // OMP51
-// OMP51-NEXT: #pragma omp for simd private(val) safelen(7) linear(lin: -5) lastprivate(res) simdlen(5) allocate(res) if(res) nontemporal(res,val,lin) order(reproducible: concurrent)
-// OMP50-NEXT: #pragma omp for simd private(val) safelen(7) linear(lin: -5) lastprivate(res) simdlen(5) allocate(res) if(res) nontemporal(res,val,lin) order(concurrent)
-// OMP45-NEXT: #pragma omp for simd private(val) safelen(7) linear(lin: -5) lastprivate(res) simdlen(5) allocate(res)
+// OMP52-NEXT: #pragma omp for simd private(val) safelen(7) linear(lin: step(-5)) lastprivate(res) simdlen(5) allocate(res) if(res) nontemporal(res,val,lin) order(reproducible: concurrent)
+// OMP51-NEXT: #pragma omp for simd private(val) safelen(7) linear(lin: step(-5)) lastprivate(res) simdlen(5) allocate(res) if(res) nontemporal(res,val,lin) order(reproducible: concurrent)
+// OMP50-NEXT: #pragma omp for simd private(val) safelen(7) linear(lin: step(-5)) lastprivate(res) simdlen(5) allocate(res) if(res) nontemporal(res,val,lin) order(concurrent)
+// OMP45-NEXT: #pragma omp for simd private(val) safelen(7) linear(lin: step(-5)) lastprivate(res) simdlen(5) allocate(res)
     for (T i = 7; i < m_a; ++i) {
       val = v[i-7] + m_a;
       res = val;
@@ -152,7 +162,7 @@ template<int LEN> struct S2 {
 // CHECK: template<> struct S2<4> {
 // 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 allocate(k1) safelen(4) linear(k1,k2: 4) aligned(a: 4) simdlen(4)
+// CHECK-NEXT: #pragma omp for simd allocate(k1) safelen(4) linear(k1,k2: step(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];
@@ -194,9 +204,10 @@ int main (int argc, char **argv) {
 #else
   #pragma omp for simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 ) simdlen(CLEN)
 #endif
-// OMP51-NEXT: #pragma omp for simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1) simdlen(CLEN)
-// OMP50-NEXT: #pragma omp for simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1) simdlen(CLEN) if(simd: a)
-// OMP45-NEXT: #pragma omp for simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1) simdlen(CLEN)
+// OMP52-NEXT: #pragma omp for simd aligned(a: CLEN) linear(a: step(CLEN)) safelen(CLEN) collapse(1) simdlen(CLEN)
+// OMP51-NEXT: #pragma omp for simd aligned(a: CLEN) linear(a: step(CLEN)) safelen(CLEN) collapse(1) simdlen(CLEN)
+// OMP50-NEXT: #pragma omp for simd aligned(a: CLEN) linear(a: step(CLEN)) safelen(CLEN) collapse(1) simdlen(CLEN) if(simd: a)
+// OMP45-NEXT: #pragma omp for simd aligned(a: CLEN) linear(a: step(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_linear_messages.cpp b/clang/test/OpenMP/for_simd_linear_messages.cpp
index 27b908739b1f2b8..a760675dcf34c31 100644
--- a/clang/test/OpenMP/for_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/for_simd_linear_messages.cpp
@@ -1,12 +1,14 @@
 // RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 extern int omp_default_mem_alloc;
 
 void xxx(int argc) {
-  int i, lin, step; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step' to silence this warning}}
-#pragma omp for simd linear(i, lin : step) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step' is uninitialized when used here}}
+  int i, lin, step_sz; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step_sz' to silence this warning}}
+#pragma omp for simd linear(i, lin : step_sz) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step_sz' is uninitialized when used here}}
   for (i = 0; i < 10; ++i)
     ;
 }
@@ -210,15 +212,35 @@ int main(int argc, char **argv) {
   #pragma omp parallel
   {
     int i;
-    #pragma omp for simd linear(i : i)
+    #pragma omp for simd linear(i)
     for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+    #pragma omp for simd linear(i : step(4))
+#else
     #pragma omp for simd linear(i : 4)
+#endif
     for (int k = 0; k < argc; ++k) { ++k; i += 4; }
   }
+#ifdef OMP52
+  #pragma omp for simd linear(j: step() //omp52-error 2 {{expected expression}} omp52-error{{expected ')'}} omp52-note{{to match this '('}}
+#else
   #pragma omp for simd linear(j)
+#endif
   for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+  #pragma omp for simd linear(i: step(1), step(2)) // omp52-error {{multiple 'step size' found in linear clause}} 
+#else
   #pragma omp for simd linear(i)
+#endif
   for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+  #pragma omp for simd linear(j: step()) // omp52-error 2 {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp for simd linear(j: pval) // omp52-error {{use of undeclared identifier 'pval'}} 
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp for simd linear(i: val, step(2 // omp52-error 3 {{expected ')'}}  omp52-note 2 {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+#endif
 
   foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
   return 0;

diff  --git a/clang/test/OpenMP/masked_taskloop_simd_linear_messages.cpp b/clang/test/OpenMP/masked_taskloop_simd_linear_messages.cpp
index 111b74f7d427c55..0bfca489ad5d151 100644
--- a/clang/test/OpenMP/masked_taskloop_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/masked_taskloop_simd_linear_messages.cpp
@@ -1,6 +1,8 @@
 // RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 typedef void **omp_allocator_handle_t;
 extern const omp_allocator_handle_t omp_null_allocator;
@@ -14,8 +16,8 @@ extern const omp_allocator_handle_t omp_pteam_mem_alloc;
 extern const omp_allocator_handle_t omp_thread_mem_alloc;
 
 void xxx(int argc) {
-  int i, lin, step; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step' to silence this warning}}
-#pragma omp master taskloop simd linear(i, lin : step) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step' is uninitialized when used here}}
+  int i, lin, step_sz; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step_sz' to silence this warning}}
+#pragma omp masked taskloop simd linear(i, lin : step_sz) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step_sz' is uninitialized when used here}}
   for (i = 0; i < 10; ++i)
     ;
 }
@@ -37,29 +39,29 @@ const int C2 = 2;
 void test_linear_colons()
 {
   int B = 0;
-  #pragma omp master taskloop simd linear(B:bfoo())
+  #pragma omp masked taskloop simd linear(B:bfoo())
   for (int i = 0; i < 10; ++i) ;
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'}}
-  #pragma omp master taskloop simd linear(B::ib:B:bfoo())
+  #pragma omp masked taskloop simd linear(B::ib:B:bfoo())
   for (int i = 0; i < 10; ++i) ;
   // expected-error at +1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
-  #pragma omp master taskloop simd linear(B:ib)
+  #pragma omp masked taskloop simd linear(B:ib)
   for (int i = 0; i < 10; ++i) ;
   // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
-  #pragma omp master taskloop simd linear(z:B:ib)
+  #pragma omp masked taskloop simd linear(z:B:ib)
   for (int i = 0; i < 10; ++i) ;
-  #pragma omp master taskloop simd linear(B:B::bfoo())
+  #pragma omp masked taskloop simd linear(B:B::bfoo())
   for (int i = 0; i < 10; ++i) ;
-  #pragma omp master taskloop simd linear(X::x : ::z)
+  #pragma omp masked taskloop simd linear(X::x : ::z)
   for (int i = 0; i < 10; ++i) ;
-  #pragma omp master taskloop simd linear(B,::z, X::x)
+  #pragma omp masked taskloop simd linear(B,::z, X::x)
   for (int i = 0; i < 10; ++i) ;
-  #pragma omp master taskloop simd linear(::z)
+  #pragma omp masked taskloop simd linear(::z)
   for (int i = 0; i < 10; ++i) ;
   // expected-error at +1 {{expected variable name}}
-  #pragma omp master taskloop simd linear(B::bfoo())
+  #pragma omp masked taskloop simd linear(B::bfoo())
   for (int i = 0; i < 10; ++i) ;
-  #pragma omp master taskloop simd linear(B::ib,B:C1+C2)
+  #pragma omp masked taskloop simd linear(B::ib,B:C1+C2)
   for (int i = 0; i < 10; ++i) ;
 }
 
@@ -68,7 +70,7 @@ template<int L, class T, class N> T test_template(T* arr, N num) {
   T sum = (T)0;
   T ind2 = - num * L; // expected-note {{'ind2' defined here}}
   // expected-error at +1 {{argument of a linear clause should be of integral or pointer type}}
-#pragma omp master taskloop simd linear(ind2:L)
+#pragma omp masked taskloop simd linear(ind2:L)
   for (i = 0; i < num; ++i) {
     T cur = arr[(int)ind2];
     ind2 += L;
@@ -80,7 +82,7 @@ template<int L, class T, class N> T test_template(T* arr, N num) {
 template<int LEN> int test_warn() {
   int ind2 = 0;
   // expected-warning at +1 {{zero linear step (ind2 should probably be const)}}
-  #pragma omp master taskloop simd linear(ind2:LEN)
+  #pragma omp masked taskloop simd linear(ind2:LEN)
   for (int i = 0; i < 100; i++) {
     ind2 += LEN;
   }
@@ -123,59 +125,66 @@ template<class I, class C> int foomain(I argc, C **argv) {
   I g(5);
   int i, z;
   int &j = i;
-  #pragma omp master taskloop simd linear // expected-error {{expected '(' after 'linear'}}
+  #pragma omp masked taskloop simd linear // expected-error {{expected '(' after 'linear'}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp masked taskloop simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear (val // expected-error {{use of undeclared identifier 'val'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp masked taskloop simd linear (val // expected-error {{use of undeclared identifier 'val'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear (uval( // expected-error {{expected expression}} expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+  #pragma omp masked taskloop simd linear (uval( // expected-error {{expected expression}} expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear (ref() // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp masked taskloop simd linear (ref() // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear (foo() // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp masked taskloop simd linear (foo() // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear () // expected-error {{expected expression}}
+  #pragma omp masked taskloop simd linear () // expected-error {{expected expression}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp masked taskloop simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear (val argc // expected-error {{use of undeclared identifier 'val'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp masked taskloop simd linear (val argc // expected-error {{use of undeclared identifier 'val'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear (val(argc, // expected-error {{expected expression}} expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+  #pragma omp masked taskloop simd linear (val(argc, // expected-error {{expected expression}} expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  #pragma omp masked taskloop simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear (argc : 5) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
+  #pragma omp masked taskloop simd linear (argc : 5) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear (S1) // expected-error {{'S1' does not refer to a value}}
+  #pragma omp masked taskloop simd linear (S1) // expected-error {{'S1' does not refer to a value}}
   for (int k = 0; k < argc; ++k) ++k;
+#if defined(OMP52)
+  // omp52-error at +3{{step simple modifier is exclusive and can't be use with 'val', 'uval' or 'ref' modifier}}
   // expected-error at +2 {{linear variable with incomplete type 'S1'}}
   // expected-error at +1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
-  #pragma omp master taskloop simd linear (val(a, b):B::ib)
+  #pragma omp masked taskloop simd linear (a, b: val, B::ib)
+#else
+  // expected-error at +2 {{linear variable with incomplete type 'S1'}}
+  // expected-error at +1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
+  #pragma omp masked taskloop simd linear (val(a, b):B::ib)
+#endif
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear (argv[1]) // expected-error {{expected variable name}}
+  #pragma omp masked taskloop simd linear (argv[1]) // expected-error {{expected variable name}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear(ref(e, g)) // expected-error 2 {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'ref'}}
+  #pragma omp masked taskloop simd linear(ref(e, g)) // expected-error 2 {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'ref'}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear(h, z) // expected-error {{threadprivate or thread local variable cannot be linear}}
+  #pragma omp masked taskloop simd linear(h, z) // expected-error {{threadprivate or thread local variable cannot be linear}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear(uval(i)) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}}
+  #pragma omp masked taskloop simd linear(uval(i)) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}}
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp parallel
   {
     int v = 0;
     int i;
-    #pragma omp master taskloop simd allocate(omp_thread_mem_alloc: v) linear(v:i) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'master taskloop simd' directive}}
+    #pragma omp masked taskloop simd allocate(omp_thread_mem_alloc: v) linear(v:i) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'masked taskloop simd' directive}}
     for (int k = 0; k < argc; ++k) { i = k; v += i; }
   }
-  #pragma omp master taskloop simd linear(ref(j))
+  #pragma omp masked taskloop simd linear(ref(j))
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear(uval(j))
+  #pragma omp masked taskloop simd linear(uval(j))
   for (int k = 0; k < argc; ++k) ++k;
   int v = 0;
-  #pragma omp master taskloop simd linear(v:j)
+  #pragma omp masked taskloop simd linear(v:j)
   for (int k = 0; k < argc; ++k) { ++k; v += j; }
-  #pragma omp master taskloop simd linear(i)
+  #pragma omp masked taskloop simd linear(i)
   for (int k = 0; k < argc; ++k) ++k;
   return 0;
 }
@@ -190,15 +199,15 @@ using A::x;
 
 void linear_modifiers(int argc) {
   int &f = argc;
-  #pragma omp master taskloop simd linear(f)
+  #pragma omp masked taskloop simd linear(f)
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear(val(f))
+  #pragma omp masked taskloop simd linear(val(f))
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear(uval(f))
+  #pragma omp masked taskloop simd linear(uval(f))
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear(ref(f))
+  #pragma omp masked taskloop simd linear(ref(f))
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear(foo(f)) // expected-error {{expected one of 'ref', val' or 'uval' modifiers}}
+  #pragma omp masked taskloop simd linear(foo(f)) // expected-error {{expected one of 'ref', val' or 'uval' modifiers}}
   for (int k = 0; k < argc; ++k) ++k;
 }
 
@@ -214,54 +223,76 @@ int main(int argc, char **argv) {
   S5 g(5); // expected-note {{'g' defined here}}
   int i, z;
   int &j = i;
-  #pragma omp master taskloop simd linear(f) linear(f) // expected-error {{linear variable cannot be linear}} expected-note {{defined as linear}}
+  #pragma omp masked taskloop simd linear(f) linear(f) // expected-error {{linear variable cannot be linear}} expected-note {{defined as linear}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear // expected-error {{expected '(' after 'linear'}}
+  #pragma omp masked taskloop simd linear // expected-error {{expected '(' after 'linear'}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp masked taskloop simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear () // expected-error {{expected expression}}
+  #pragma omp masked taskloop simd linear () // expected-error {{expected expression}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear (val // expected-error {{use of undeclared identifier 'val'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp masked taskloop simd linear (val // expected-error {{use of undeclared identifier 'val'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear (ref()) // expected-error {{expected expression}}
+  #pragma omp masked taskloop simd linear (ref()) // expected-error {{expected expression}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear (foo()) // expected-error {{expected expression}}
+  #pragma omp masked taskloop simd linear (foo()) // expected-error {{expected expression}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp masked taskloop simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp masked taskloop simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  #pragma omp masked taskloop simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear (argc, z)
+  #pragma omp masked taskloop simd linear (argc, z)
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear (S1) // expected-error {{'S1' does not refer to a value}}
+  #pragma omp masked taskloop simd linear (S1) // expected-error {{'S1' does not refer to a value}}
   for (int k = 0; k < argc; ++k) ++k;
   // expected-error at +2 {{linear variable with incomplete type 'S1'}}
   // expected-error at +1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
-  #pragma omp master taskloop simd linear(a, b)
+  #pragma omp masked taskloop simd linear(a, b)
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear (argv[1]) // expected-error {{expected variable name}}
+  #pragma omp masked taskloop simd linear (argv[1]) // expected-error {{expected variable name}}
   for (int k = 0; k < argc; ++k) ++k;
   // expected-error at +2 {{argument of a linear clause should be of integral or pointer type, not 'S4'}}
   // expected-error at +1 {{argument of a linear clause should be of integral or pointer type, not 'S5'}}
-  #pragma omp master taskloop simd linear(val(e, g))
+  #pragma omp masked taskloop simd linear(val(e, g))
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}}
+  #pragma omp masked taskloop simd linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}}
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp parallel
   {
     int i;
-    #pragma omp master taskloop simd linear(val(i))
+    #pragma omp masked taskloop simd linear(val(i))
     for (int k = 0; k < argc; ++k) ++k;
-    #pragma omp master taskloop simd linear(uval(i) : 4) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}}
+#ifdef OMP52
+    #pragma omp masked taskloop simd linear(i : uval, step(4)) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}}
+#else
+    #pragma omp masked taskloop simd linear(uval(i) : 4) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}}
+#endif
     for (int k = 0; k < argc; ++k) { ++k; i += 4; }
   }
-  #pragma omp master taskloop simd linear(ref(j))
+#ifdef OMP52
+  #pragma omp masked taskloop simd linear(j: ref)
+#else  
+  #pragma omp masked taskloop simd linear(ref(j))
+#endif
+  for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+  #pragma omp masked taskloop simd linear(i: step(1), step(2)) // omp52-error {{multiple 'step size' found in linear clause}}
+#else  
+  #pragma omp masked taskloop simd linear(i)
+#endif
+  for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+  #pragma omp masked taskloop simd linear(i: val, val) // omp52-error {{multiple 'linear modifier' found in linear clause}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp masked taskloop simd linear(j: step()) // omp52-error 2 {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp masked taskloop simd linear(j: pval) // omp52-error {{use of undeclared identifier 'pval'}}
   for (int k = 0; k < argc; ++k) ++k;
-  #pragma omp master taskloop simd linear(i)
+  #pragma omp masked taskloop simd linear(i: val, step(2 // omp52-error {{expected ')' or ',' after 'step expression'}} omp52-error 2 {{expected ')'}}  omp52-note 2 {{to match this '('}}
   for (int k = 0; k < argc; ++k) ++k;
+#endif
 
   foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
   return 0;

diff  --git a/clang/test/OpenMP/master_taskloop_simd_linear_messages.cpp b/clang/test/OpenMP/master_taskloop_simd_linear_messages.cpp
index 111b74f7d427c55..cb8ed2940a2515e 100644
--- a/clang/test/OpenMP/master_taskloop_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/master_taskloop_simd_linear_messages.cpp
@@ -1,6 +1,8 @@
 // RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 typedef void **omp_allocator_handle_t;
 extern const omp_allocator_handle_t omp_null_allocator;
@@ -14,8 +16,8 @@ extern const omp_allocator_handle_t omp_pteam_mem_alloc;
 extern const omp_allocator_handle_t omp_thread_mem_alloc;
 
 void xxx(int argc) {
-  int i, lin, step; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step' to silence this warning}}
-#pragma omp master taskloop simd linear(i, lin : step) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step' is uninitialized when used here}}
+  int i, lin, step_sz; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step_sz' to silence this warning}}
+#pragma omp master taskloop simd linear(i, lin : step_sz) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step_sz' is uninitialized when used here}}
   for (i = 0; i < 10; ++i)
     ;
 }
@@ -149,9 +151,16 @@ template<class I, class C> int foomain(I argc, C **argv) {
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp master taskloop simd linear (S1) // expected-error {{'S1' does not refer to a value}}
   for (int k = 0; k < argc; ++k) ++k;
+#if defined(OMP52)
+  // omp52-error at +3{{step simple modifier is exclusive and can't be use with 'val', 'uval' or 'ref' modifier}}
+  // expected-error at +2 {{linear variable with incomplete type 'S1'}}
+  // expected-error at +1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
+  #pragma omp master taskloop simd linear (a, b: val, B::ib)
+#else
   // expected-error at +2 {{linear variable with incomplete type 'S1'}}
   // expected-error at +1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   #pragma omp master taskloop simd linear (val(a, b):B::ib)
+#endif
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp master taskloop simd linear (argv[1]) // expected-error {{expected variable name}}
   for (int k = 0; k < argc; ++k) ++k;
@@ -255,13 +264,35 @@ int main(int argc, char **argv) {
     int i;
     #pragma omp master taskloop simd linear(val(i))
     for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+    #pragma omp master taskloop simd linear(i : uval, step(4)) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}}
+#else
     #pragma omp master taskloop simd linear(uval(i) : 4) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}}
+#endif
     for (int k = 0; k < argc; ++k) { ++k; i += 4; }
   }
+#ifdef OMP52
+  #pragma omp master taskloop simd linear(j: ref)
+#else  
   #pragma omp master taskloop simd linear(ref(j))
+#endif
   for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+  #pragma omp master taskloop simd linear(i: step(1), step(2)) // omp52-error {{multiple 'step size' found in linear clause}}
+#else  
   #pragma omp master taskloop simd linear(i)
+#endif
+  for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+  #pragma omp master taskloop simd linear(i: val, val) // omp52-error {{multiple 'linear modifier' found in linear clause}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp master taskloop simd linear(j: step()) // omp52-error 2 {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp master taskloop simd linear(j: pval) // omp52-error {{use of undeclared identifier 'pval'}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp master taskloop simd linear(i: val, step(2 // omp52-error {{expected ')' or ',' after 'step expression'}} omp52-error 2 {{expected ')'}}  omp52-note 2 {{to match this '('}}
   for (int k = 0; k < argc; ++k) ++k;
+#endif
 
   foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
   return 0;

diff  --git a/clang/test/OpenMP/parallel_for_ast_print.cpp b/clang/test/OpenMP/parallel_for_ast_print.cpp
index f9f6a8aa01d286f..df5e7596f6a9051 100644
--- a/clang/test/OpenMP/parallel_for_ast_print.cpp
+++ b/clang/test/OpenMP/parallel_for_ast_print.cpp
@@ -4,6 +4,9 @@
 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -ast-print %s -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51
 // RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51
 // RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -ast-print %s -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP52
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s --check-prefix=CHECK --check-prefix=OMP50
 // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s
@@ -12,6 +15,10 @@
 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=51 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51
 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=51 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51
 // expected-no-diagnostics
+// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -ast-print %s -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP52
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
+// expected-no-diagnostics
 
 #ifndef HEADER
 #define HEADER
@@ -76,13 +83,14 @@ T tmain(T argc) {
 // CHECK: static T a;
   static T g;
 #pragma omp threadprivate(g)
-#ifdef OMP51
+#if defined(OMP51) || defined(OMP52)
 #pragma omp parallel for schedule(dynamic) default(none) copyin(g) linear(a) allocate(a) lastprivate(conditional: d, e,f) order(reproducible:concurrent)
 #else
 #pragma omp parallel for schedule(dynamic) default(none) copyin(g) linear(a) allocate(a) lastprivate(conditional: d, e,f) order(concurrent)
 #endif // OMP51
   // OMP50: #pragma omp parallel for schedule(dynamic) default(none) copyin(g) linear(a) allocate(a) lastprivate(conditional: d,e,f) order(concurrent)
   // OMP51: #pragma omp parallel for schedule(dynamic) default(none) copyin(g) linear(a) allocate(a) lastprivate(conditional: d,e,f) order(reproducible: concurrent)
+  // OMP52: #pragma omp parallel for schedule(dynamic) default(none) copyin(g) linear(a) allocate(a) lastprivate(conditional: d,e,f) order(reproducible: concurrent)
   for (int i = 0; i < 2; ++i)
     a = 2;
 // CHECK-NEXT: for (int i = 0; i < 2; ++i)
@@ -149,11 +157,15 @@ int main(int argc, char **argv) {
     a = 2;
 // CHECK-NEXT: for (int i = 0; i < 2; ++i)
 // CHECK-NEXT: a = 2;
+#ifdef OMP52
+#pragma omp parallel for private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) ordered if (argc) num_threads(a) default(shared) shared(e) reduction(+ : h) linear(a: step(-5))
+#else
 #pragma omp parallel for private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) ordered if (argc) num_threads(a) default(shared) shared(e) reduction(+ : h) linear(a:-5)
+#endif
   for (int i = 0; i < 10; ++i)
     for (int j = 0; j < 10; ++j)
       foo();
-  // CHECK-NEXT: #pragma omp parallel for private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) ordered if(argc) num_threads(a) default(shared) shared(e) reduction(+: h) linear(a: -5)
+  // CHECK-NEXT: #pragma omp parallel for private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) ordered if(argc) num_threads(a) default(shared) shared(e) reduction(+: h) linear(a: step(-5))
  // CHECK-NEXT: for (int i = 0; i < 10; ++i)
   // CHECK-NEXT: for (int j = 0; j < 10; ++j)
   // CHECK-NEXT: foo();

diff  --git a/clang/test/OpenMP/parallel_for_linear_messages.cpp b/clang/test/OpenMP/parallel_for_linear_messages.cpp
index a6dc1fdde63c28b..4e863de79fe0e46 100644
--- a/clang/test/OpenMP/parallel_for_linear_messages.cpp
+++ b/clang/test/OpenMP/parallel_for_linear_messages.cpp
@@ -1,12 +1,14 @@
 // RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 extern int omp_default_mem_alloc;
 
 void xxx(int argc) {
-  int i, lin, step; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step' to silence this warning}}
-#pragma omp parallel for linear(lin : step) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step' is uninitialized when used here}}
+  int i, lin, step_sz; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step_sz' to silence this warning}}
+#pragma omp parallel for linear(lin : step_sz) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step_sz' is uninitialized when used here}}
   for (i = 0; i < 10; ++i)
     ;
 }
@@ -261,16 +263,28 @@ int main(int argc, char **argv) {
 #pragma omp parallel for linear(i)
     for (int k = 0; k < argc; ++k)
       ++k;
+#ifdef OMP52
+#pragma omp parallel for linear(i : step(4))
+#else
 #pragma omp parallel for linear(i : 4)
+#endif
     for (int k = 0; k < argc; ++k) {
       ++k;
       i += 4;
     }
   }
-#pragma omp parallel for linear(j)
+#ifdef OMP52
+#pragma omp for linear(j: step() //omp52-error 2 {{expected expression}} omp52-error{{expected ')'}} omp52-note{{to match this '('}}
+#else
+#pragma omp for linear(j)
+#endif
   for (int k = 0; k < argc; ++k)
     ++k;
-#pragma omp parallel for linear(i)
+#ifdef OMP52
+  #pragma omp for linear(i: step(1), step(2)) // omp52-error {{multiple 'step size' found in linear clause}}
+#else
+  #pragma omp for linear(i)
+#endif
   for (int k = 0; k < argc; ++k)
     ++k;
 

diff  --git a/clang/test/OpenMP/parallel_for_simd_ast_print.cpp b/clang/test/OpenMP/parallel_for_simd_ast_print.cpp
index 8b2b21e505ce402..69c21f5bdfdf68f 100644
--- a/clang/test/OpenMP/parallel_for_simd_ast_print.cpp
+++ b/clang/test/OpenMP/parallel_for_simd_ast_print.cpp
@@ -104,7 +104,7 @@ template<class T> struct S {
 // CHECK: T val;
 // CHECK: T lin = 0;
     #pragma omp parallel for simd private(val)  safelen(7) linear(lin : -5) lastprivate(res) simdlen(5) if(7) allocate(lin)
-// CHECK-NEXT: #pragma omp parallel for simd private(val) safelen(7) linear(lin: -5) lastprivate(res) simdlen(5) if(7) allocate(lin)
+// CHECK-NEXT: #pragma omp parallel for simd private(val) safelen(7) linear(lin: step(-5)) lastprivate(res) simdlen(5) if(7) allocate(lin)
     for (T i = 7; i < m_a; ++i) {
       val = v[i-7] + m_a;
       res = val;
@@ -145,7 +145,7 @@ template<int LEN> struct S2 {
 // CHECK: template<> struct S2<4> {
 // 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 allocate(k1) safelen(4) linear(k1,k2: 4) aligned(a: 4) simdlen(4)
+// CHECK-NEXT: #pragma omp parallel for simd allocate(k1) safelen(4) linear(k1,k2: step(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];
@@ -191,7 +191,7 @@ int main (int argc, char **argv) {
   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 ) simdlen(CLEN)
-// CHECK-NEXT: #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: step(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_linear_messages.cpp b/clang/test/OpenMP/parallel_for_simd_linear_messages.cpp
index 6ca28adad04fd78..ab682e29cd93c1a 100644
--- a/clang/test/OpenMP/parallel_for_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/parallel_for_simd_linear_messages.cpp
@@ -1,11 +1,13 @@
 // RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 extern int omp_default_mem_alloc;
 void xxx(int argc) {
-  int i, lin, step; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step' to silence this warning}}
-#pragma omp parallel for simd linear(i, lin : step) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step' is uninitialized when used here}}
+  int i, lin, step_sz; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step_sz' to silence this warning}}
+#pragma omp parallel for simd linear(i, lin : step_sz) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step_sz' is uninitialized when used here}}
   for (i = 0; i < 10; ++i)
     ;
 }
@@ -210,12 +212,24 @@ int main(int argc, char **argv) {
     int i;
     #pragma omp parallel for simd linear(i)
     for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+    #pragma omp parallel for simd linear(i : step(4))
+#else
     #pragma omp parallel for simd linear(i : 4)
+#endif
     for (int k = 0; k < argc; ++k) { ++k; i += 4; }
   }
+#ifdef OMP52
+  #pragma omp for linear(j: step() //omp52-error 2 {{expected expression}} omp52-error{{expected ')'}} omp52-note{{to match this '('}}
+#else
   #pragma omp parallel for simd linear(j)
+#endif
   for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+  #pragma omp for linear(i: step(1), step(2)) // omp52-error {{multiple 'step size' found in linear clause}}
+#else
   #pragma omp parallel for simd linear(i)
+#endif
   for (int k = 0; k < argc; ++k) ++k;
 
   foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}

diff  --git a/clang/test/OpenMP/parallel_masked_taskloop_simd_ast_print.cpp b/clang/test/OpenMP/parallel_masked_taskloop_simd_ast_print.cpp
index 888e123d2a5128a..1d01ac9a668c85f 100644
--- a/clang/test/OpenMP/parallel_masked_taskloop_simd_ast_print.cpp
+++ b/clang/test/OpenMP/parallel_masked_taskloop_simd_ast_print.cpp
@@ -62,7 +62,7 @@ int main(int argc, char **argv) {
 #pragma omp taskgroup task_reduction(+: d)
 #pragma omp parallel masked taskloop simd if(parallel: a) default(none) shared(a, b, argc) final(b) priority(5) num_tasks(argc) reduction(*: g) aligned(argv: 8) linear(c:b) filter(tid)
   // CHECK-NEXT: #pragma omp taskgroup task_reduction(+: d)
-  // CHECK-NEXT: #pragma omp parallel masked taskloop simd if(parallel: a) default(none) shared(a,b,argc) final(b) priority(5) num_tasks(argc) reduction(*: g) aligned(argv: 8) linear(c: b) filter(tid)
+  // CHECK-NEXT: #pragma omp parallel masked taskloop simd if(parallel: a) default(none) shared(a,b,argc) final(b) priority(5) num_tasks(argc) reduction(*: g) aligned(argv: 8) linear(c: step(b)) filter(tid)
   for (int i = 0; i < 2; ++i)
     a = 2;
 // CHECK-NEXT: for (int i = 0; i < 2; ++i)

diff  --git a/clang/test/OpenMP/parallel_masked_taskloop_simd_linear_messages.cpp b/clang/test/OpenMP/parallel_masked_taskloop_simd_linear_messages.cpp
index 767d683a8076603..b63f88409c9c861 100644
--- a/clang/test/OpenMP/parallel_masked_taskloop_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/parallel_masked_taskloop_simd_linear_messages.cpp
@@ -1,6 +1,8 @@
 // RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 typedef void **omp_allocator_handle_t;
 extern const omp_allocator_handle_t omp_null_allocator;
@@ -14,8 +16,8 @@ extern const omp_allocator_handle_t omp_pteam_mem_alloc;
 extern const omp_allocator_handle_t omp_thread_mem_alloc;
 
 void xxx(int argc) {
-  int i, lin, step; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step' to silence this warning}}
-#pragma omp parallel masked taskloop simd linear(i, lin : step) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step' is uninitialized when used here}}
+  int i, lin, step_sz; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step_sz' to silence this warning}}
+#pragma omp parallel masked taskloop simd linear(i, lin : step_sz) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step_sz' is uninitialized when used here}}
   for (i = 0; i < 10; ++i)
     ;
 }
@@ -149,9 +151,16 @@ template<class I, class C> int foomain(I argc, C **argv) {
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp parallel masked taskloop simd linear (S1) // expected-error {{'S1' does not refer to a value}}
   for (int k = 0; k < argc; ++k) ++k;
+#if defined(OMP52)
+  // omp52-error at +3{{step simple modifier is exclusive and can't be use with 'val', 'uval' or 'ref' modifier}}
+  // expected-error at +2 {{linear variable with incomplete type 'S1'}}
+  // expected-error at +1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
+  #pragma omp parallel masked taskloop simd linear (a, b: val, B::ib)
+#else
   // expected-error at +2 {{linear variable with incomplete type 'S1'}}
   // expected-error at +1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   #pragma omp parallel masked taskloop simd linear (val(a, b):B::ib)
+#endif
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp parallel masked taskloop simd linear (argv[1]) // expected-error {{expected variable name}}
   for (int k = 0; k < argc; ++k) ++k;
@@ -255,13 +264,33 @@ int main(int argc, char **argv) {
     int i;
     #pragma omp parallel masked taskloop simd linear(val(i))
     for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+    #pragma omp parallel masked taskloop simd linear(i : uval, step(4)) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}}
+#else
     #pragma omp parallel masked taskloop simd linear(uval(i) : 4) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}}
+#endif
     for (int k = 0; k < argc; ++k) { ++k; i += 4; }
   }
+#ifdef OMP52
+  #pragma omp parallel masked taskloop simd linear(j: ref)
+#else  
   #pragma omp parallel masked taskloop simd linear(ref(j))
+#endif
   for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+  #pragma omp parallel masked taskloop simd linear(i: step(1), step(2)) // omp52-error {{multiple 'step size' found in linear clause}} 
+#else  
   #pragma omp parallel masked taskloop simd linear(i)
+#endif
+  for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+  #pragma omp parallel masked taskloop simd linear(j: step()) // omp52-error 2 {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp parallel masked taskloop simd linear(j: pval) // omp52-error {{use of undeclared identifier 'pval'}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp parallel masked taskloop simd linear(i: val, step(2 // omp52-error {{expected ')' or ',' after 'step expression'}} omp52-error 2 {{expected ')'}}  omp52-note 2 {{to match this '('}}
   for (int k = 0; k < argc; ++k) ++k;
+#endif
 
   foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
   return 0;

diff  --git a/clang/test/OpenMP/parallel_master_taskloop_simd_ast_print.cpp b/clang/test/OpenMP/parallel_master_taskloop_simd_ast_print.cpp
index a85c232265d9947..441e16c268b1f9a 100644
--- a/clang/test/OpenMP/parallel_master_taskloop_simd_ast_print.cpp
+++ b/clang/test/OpenMP/parallel_master_taskloop_simd_ast_print.cpp
@@ -68,7 +68,7 @@ int main(int argc, char **argv) {
 #pragma omp taskgroup task_reduction(+: d)
 #pragma omp parallel master taskloop simd if(parallel: a) default(none) shared(a, b, argc) final(b) priority(5) num_tasks(argc) reduction(*: g) aligned(argv: 8) linear(c:b)
   // CHECK-NEXT: #pragma omp taskgroup task_reduction(+: d)
-  // CHECK-NEXT: #pragma omp parallel master taskloop simd if(parallel: a) default(none) shared(a,b,argc) final(b) priority(5) num_tasks(argc) reduction(*: g) aligned(argv: 8) linear(c: b)
+  // CHECK-NEXT: #pragma omp parallel master taskloop simd if(parallel: a) default(none) shared(a,b,argc) final(b) priority(5) num_tasks(argc) reduction(*: g) aligned(argv: 8) linear(c: step(b))
   for (int i = 0; i < 2; ++i)
     a = 2;
 // CHECK-NEXT: for (int i = 0; i < 2; ++i)

diff  --git a/clang/test/OpenMP/parallel_master_taskloop_simd_linear_messages.cpp b/clang/test/OpenMP/parallel_master_taskloop_simd_linear_messages.cpp
index 45cad614a73174f..95cfc4eefce34ea 100644
--- a/clang/test/OpenMP/parallel_master_taskloop_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/parallel_master_taskloop_simd_linear_messages.cpp
@@ -1,6 +1,8 @@
 // RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 typedef void **omp_allocator_handle_t;
 extern const omp_allocator_handle_t omp_null_allocator;
@@ -14,8 +16,8 @@ extern const omp_allocator_handle_t omp_pteam_mem_alloc;
 extern const omp_allocator_handle_t omp_thread_mem_alloc;
 
 void xxx(int argc) {
-  int i, lin, step; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step' to silence this warning}}
-#pragma omp parallel master taskloop simd linear(i, lin : step) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step' is uninitialized when used here}}
+  int i, lin, step_sz; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step_sz' to silence this warning}}
+#pragma omp parallel master taskloop simd linear(i, lin : step_sz) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step_sz' is uninitialized when used here}}
   for (i = 0; i < 10; ++i)
     ;
 }
@@ -149,9 +151,16 @@ template<class I, class C> int foomain(I argc, C **argv) {
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp parallel master taskloop simd linear (S1) // expected-error {{'S1' does not refer to a value}}
   for (int k = 0; k < argc; ++k) ++k;
+#if defined(OMP52)
+  // omp52-error at +3{{step simple modifier is exclusive and can't be use with 'val', 'uval' or 'ref' modifier}}
+  // expected-error at +2 {{linear variable with incomplete type 'S1'}}
+  // expected-error at +1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
+  #pragma omp parallel master taskloop simd linear (a, b: val, B::ib)
+#else
   // expected-error at +2 {{linear variable with incomplete type 'S1'}}
   // expected-error at +1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   #pragma omp parallel master taskloop simd linear (val(a, b):B::ib)
+#endif
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp parallel master taskloop simd linear (argv[1]) // expected-error {{expected variable name}}
   for (int k = 0; k < argc; ++k) ++k;
@@ -255,13 +264,33 @@ int main(int argc, char **argv) {
     int i;
     #pragma omp parallel master taskloop simd linear(val(i))
     for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+    #pragma omp parallel master taskloop simd linear(i : uval, step(4)) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}}
+#else
     #pragma omp parallel master taskloop simd linear(uval(i) : 4) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}}
+#endif
     for (int k = 0; k < argc; ++k) { ++k; i += 4; }
   }
+#ifdef OMP52
+  #pragma omp parallel master taskloop simd linear(j: ref)
+#else  
   #pragma omp parallel master taskloop simd linear(ref(j))
+#endif
   for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+  #pragma omp parallel master taskloop simd linear(i: step(1), step(2)) // omp52-error {{multiple 'step size' found in linear clause}}
+#else  
   #pragma omp parallel master taskloop simd linear(i)
+#endif
+  for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+  #pragma omp parallel master taskloop simd linear(j: step()) // omp52-error 2 {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp parallel master taskloop simd linear(j: pval) // omp52-error {{use of undeclared identifier 'pval'}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp parallel master taskloop simd linear(i: val, step(2 // omp52-error {{expected ')' or ',' after 'step expression'}} omp52-error 2 {{expected ')'}}  omp52-note 2 {{to match this '('}}
   for (int k = 0; k < argc; ++k) ++k;
+#endif
 
   foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
   return 0;

diff  --git a/clang/test/OpenMP/simd_ast_print.cpp b/clang/test/OpenMP/simd_ast_print.cpp
index 7f98d351e7edc82..057f1e7c03c0ec2 100644
--- a/clang/test/OpenMP/simd_ast_print.cpp
+++ b/clang/test/OpenMP/simd_ast_print.cpp
@@ -7,6 +7,9 @@
 // RUN: %clang_cc1 -verify -fopenmp -ast-print %s -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51
 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51
 // RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -ast-print %s -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP52
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=45 -ast-print %s | FileCheck %s --check-prefix=CHECK --check-prefix=OMP45
 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s
@@ -18,6 +21,10 @@
 // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51
 // RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51
 // expected-no-diagnostics
+// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -ast-print %s -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP52
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
+// expected-no-diagnostics
 
 #ifndef HEADER
 #define HEADER
@@ -80,11 +87,15 @@ template<class T, class N> T reduct(T* arr, N num) {
   N i;
   N ind;
   N myind;
-  N &ref = i;
+  N &r = i;
   T sum = (T)0;
 // CHECK: T sum = (T)0;
-#pragma omp simd private(myind, g_ind), linear(ind), aligned(arr), linear(uval(ref))
-// CHECK-NEXT: #pragma omp simd private(myind,g_ind) linear(ind) aligned(arr) linear(uval(ref))
+#ifdef OMP52
+#pragma omp simd private(myind, g_ind), linear(ind), aligned(arr), linear(r: uval)
+#else
+#pragma omp simd private(myind, g_ind), linear(ind), aligned(arr), linear(uval(r))
+#endif
+// CHECK-NEXT: #pragma omp simd private(myind,g_ind) linear(ind) aligned(arr) linear(r: uval)
   for (i = 0; i < num; ++i) {
     myind = ind;
     T cur = arr[myind];
@@ -101,13 +112,17 @@ template<class T> struct S {
     T res;
     T val;
     T lin = 0;
-    T &ref = res;
+    T &r = res;
 // CHECK: T res;
 // CHECK: T val;
 // CHECK: T lin = 0;
-// CHECK: T &ref = res;
-    #pragma omp simd allocate(res) private(val)  safelen(7) linear(lin : -5) lastprivate(res) simdlen(5) linear(ref(ref))
-// CHECK-NEXT: #pragma omp simd allocate(res) private(val) safelen(7) linear(lin: -5) lastprivate(res) simdlen(5) linear(ref(ref))
+// CHECK: T &r = res;
+#ifdef OMP52
+    #pragma omp simd allocate(res) private(val)  safelen(7) linear(lin : step(-5)) lastprivate(res) simdlen(5) linear(r: ref)
+#else
+    #pragma omp simd allocate(res) private(val)  safelen(7) linear(lin : -5) lastprivate(res) simdlen(5) linear(ref(r))
+#endif
+// CHECK-NEXT: #pragma omp simd allocate(res) private(val) safelen(7) linear(lin: step(-5)) lastprivate(res) simdlen(5) linear(r: ref)
     for (T i = 7; i < m_a; ++i) {
       val = v[i-7] + m_a;
       res = val;
@@ -148,7 +163,7 @@ template<int LEN> struct S2 {
 // CHECK: template<> struct S2<4> {
 // 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) simdlen(4) allocate(k1)
+// CHECK-NEXT: #pragma omp simd safelen(4) linear(k1,k2: step(4)) aligned(a: 4) simdlen(4) allocate(k1)
 // 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];
@@ -161,7 +176,7 @@ template<int LEN> struct S2 {
 int main (int argc, char **argv) {
   int b = argc, c, d, e, f, g;
   int k1=0,k2=0;
-  int &ref = b;
+  int &r = b;
   static int *a;
 // CHECK: static int *a;
 #pragma omp simd
@@ -169,7 +184,10 @@ int main (int argc, char **argv) {
   for (int i=0; i < 2; ++i)*a=2;
 // CHECK-NEXT: for (int i = 0; i < 2; ++i)
 // CHECK-NEXT: *a = 2;
-#ifdef OMP51
+#ifdef OMP52
+#pragma omp simd private(argc, b),lastprivate(d,f) collapse(2) aligned(a : 4) if(simd:a) nontemporal(argc, c, d) lastprivate(conditional: e, f) order(unconstrained:concurrent)
+// OMP52-NEXT: #pragma omp simd private(argc,b) lastprivate(d,f) collapse(2) aligned(a: 4) if(simd: a) nontemporal(argc,c,d) lastprivate(conditional: e,f) order(unconstrained: concurrent)
+#elif OMP51
 #pragma omp simd private(argc, b),lastprivate(d,f) collapse(2) aligned(a : 4) if(simd:a) nontemporal(argc, c, d) lastprivate(conditional: e, f) order(unconstrained:concurrent)
 // OMP51-NEXT: #pragma omp simd private(argc,b) lastprivate(d,f) collapse(2) aligned(a: 4) if(simd: a) nontemporal(argc,c,d) lastprivate(conditional: e,f) order(unconstrained: concurrent)
 #elif OMP5
@@ -192,13 +210,16 @@ int main (int argc, char **argv) {
 // CHECK-NEXT: foo();
   const int CLEN = 4;
 // CHECK-NEXT: const int CLEN = 4;
-#ifdef OMP5
-  #pragma omp simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 ) simdlen(CLEN) linear(val(ref): CLEN) if(a)
-// OMP50-NEXT: #pragma omp simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1) simdlen(CLEN) linear(val(ref): CLEN) if(a)
+#ifdef OMP52  
+  #pragma omp simd aligned(a:CLEN) linear(a: step(CLEN)) safelen(CLEN) collapse( 1 ) simdlen(CLEN) linear(r: val, step(CLEN)) if(a)
+#elif OMP5
+  #pragma omp simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 ) simdlen(CLEN) linear(val(r): CLEN) if(a)
+// OMP50-NEXT: #pragma omp simd aligned(a: CLEN) linear(a: step(CLEN)) safelen(CLEN) collapse(1) simdlen(CLEN) linear(r: val, step(CLEN)) if(a)
 #else
-  #pragma omp simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 ) simdlen(CLEN) linear(val(ref): CLEN)
-// OMP45-NEXT: #pragma omp simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1) simdlen(CLEN) linear(val(ref): CLEN)
-// OMP51-NEXT: #pragma omp simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1) simdlen(CLEN) linear(val(ref): CLEN)
+  #pragma omp simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 ) simdlen(CLEN) linear(val(r): CLEN)
+// OMP45-NEXT: #pragma omp simd aligned(a: CLEN) linear(a: step(CLEN)) safelen(CLEN) collapse(1) simdlen(CLEN) linear(r: val, step(CLEN))
+// OMP51-NEXT: #pragma omp simd aligned(a: CLEN) linear(a: step(CLEN)) safelen(CLEN) collapse(1) simdlen(CLEN) linear(r: val, step(CLEN))
+// OMP52-NEXT: #pragma omp simd aligned(a: CLEN) linear(a: step(CLEN)) safelen(CLEN) collapse(1) simdlen(CLEN) linear(r: val, step(CLEN))
 #endif // OMP5
   for (int i = 0; i < 10; ++i)foo();
 // CHECK-NEXT: for (int i = 0; i < 10; ++i)

diff  --git a/clang/test/OpenMP/simd_linear_messages.cpp b/clang/test/OpenMP/simd_linear_messages.cpp
index 92637fbc880d08d..3cf772d41c67b2f 100644
--- a/clang/test/OpenMP/simd_linear_messages.cpp
+++ b/clang/test/OpenMP/simd_linear_messages.cpp
@@ -1,11 +1,13 @@
 // RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 extern int omp_default_mem_alloc;
 void xxx(int argc) {
-  int i, lin, step; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step' to silence this warning}}
-#pragma omp simd linear(i, lin : step) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step' is uninitialized when used here}}
+  int i, lin, step_sz; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step_sz' to silence this warning}}
+#pragma omp simd linear(i, lin : step_sz) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step_sz' is uninitialized when used here}}
   for (i = 0; i < 10; ++i)
     ;
 }
@@ -139,9 +141,16 @@ template<class I, class C> int foomain(I argc, C **argv) {
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp simd linear (S1) // expected-error {{'S1' does not refer to a value}}
   for (int k = 0; k < argc; ++k) ++k;
+#if defined(OMP52)
+  // omp52-error at +3{{step simple modifier is exclusive and can't be use with 'val', 'uval' or 'ref' modifier}}
+  // expected-error at +2 {{linear variable with incomplete type 'S1'}}
+  // expected-error at +1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
+  #pragma omp simd linear (a, b: val, B::ib)
+#else
   // expected-error at +2 {{linear variable with incomplete type 'S1'}}
   // expected-error at +1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   #pragma omp simd linear (val(a, b):B::ib)
+#endif
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp simd linear (argv[1]) // expected-error {{expected variable name}}
   for (int k = 0; k < argc; ++k) ++k;
@@ -245,13 +254,35 @@ int main(int argc, char **argv) {
     int i;
     #pragma omp simd linear(val(i))
     for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+    #pragma omp simd linear(i : uval, step(4)) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}}
+#else
     #pragma omp simd linear(uval(i) : 4) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}}
+#endif
     for (int k = 0; k < argc; ++k) { ++k; i += 4; }
   }
+#ifdef OMP52
+  #pragma omp simd linear(j: ref)
+#else  
   #pragma omp simd linear(ref(j))
+#endif
   for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+  #pragma omp simd linear(i: step(1), step(2)) // omp52-error {{multiple 'step size' found in linear clause}}
+#else  
   #pragma omp simd linear(i)
+#endif
+  for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+  #pragma omp simd linear(i: val, val) // omp52-error {{multiple 'linear modifier' found in linear clause}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd linear(j: step()) // omp52-error 2 {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd linear(j: pval) // omp52-error {{use of undeclared identifier 'pval'}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd linear(i: val, step(2 // omp52-error {{expected ')' or ',' after 'step expression'}} omp52-error 2 {{expected ')'}}  omp52-note 2 {{to match this '('}}
   for (int k = 0; k < argc; ++k) ++k;
+#endif
 
   foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
   return 0;

diff  --git a/clang/test/OpenMP/target_parallel_for_ast_print.cpp b/clang/test/OpenMP/target_parallel_for_ast_print.cpp
index 6edbc26a11ab5f1..16c2175099acd4e 100644
--- a/clang/test/OpenMP/target_parallel_for_ast_print.cpp
+++ b/clang/test/OpenMP/target_parallel_for_ast_print.cpp
@@ -208,7 +208,7 @@ int main(int argc, char **argv) {
   for (int i = 0; i < 10; ++i)
     for (int j = 0; j < 10; ++j)
       foo();
-  // CHECK-NEXT: #pragma omp target parallel for private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) ordered if(target: argc) num_threads(a) default(shared) shared(e) reduction(+: h) linear(a: -5)
+  // CHECK-NEXT: #pragma omp target parallel for private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) ordered if(target: argc) num_threads(a) default(shared) shared(e) reduction(+: h) linear(a: step(-5))
  // CHECK-NEXT: for (int i = 0; i < 10; ++i)
   // CHECK-NEXT: for (int j = 0; j < 10; ++j)
   // CHECK-NEXT: foo();

diff  --git a/clang/test/OpenMP/target_parallel_for_linear_messages.cpp b/clang/test/OpenMP/target_parallel_for_linear_messages.cpp
index 1d79b2c38303f27..5a78cf0623f616d 100644
--- a/clang/test/OpenMP/target_parallel_for_linear_messages.cpp
+++ b/clang/test/OpenMP/target_parallel_for_linear_messages.cpp
@@ -1,6 +1,8 @@
 // RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 typedef void **omp_allocator_handle_t;
 extern const omp_allocator_handle_t omp_null_allocator;
@@ -14,8 +16,8 @@ extern const omp_allocator_handle_t omp_pteam_mem_alloc;
 extern const omp_allocator_handle_t omp_thread_mem_alloc;
 
 void xxx(int argc) {
-  int i, lin, step; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step' to silence this warning}}
-#pragma omp target parallel for linear(lin : step) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step' is uninitialized when used here}}
+  int i, lin, step_sz; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step_sz' to silence this warning}}
+#pragma omp target parallel for linear(lin : step_sz) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step_sz' is uninitialized when used here}}
   for (i = 0; i < 10; ++i)
     ;
 }
@@ -270,16 +272,28 @@ int main(int argc, char **argv) {
 #pragma omp target parallel for linear(i)
     for (int k = 0; k < argc; ++k)
       ++k;
+#ifdef OMP52
+#pragma omp target parallel for linear(i : uval, step(4)) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}}
+#else
 #pragma omp target parallel for linear(i : 4)
+#endif
     for (int k = 0; k < argc; ++k) {
       ++k;
       i += 4;
     }
   }
+#ifdef OMP52
+#pragma omp target parallel for linear(j: step() //omp52-error 2 {{expected expression}} omp52-error{{expected ')'}} omp52-note{{to match this '('}}
+#else
 #pragma omp target parallel for linear(j)
+#endif
   for (int k = 0; k < argc; ++k)
     ++k;
+#ifdef OMP52
+#pragma omp target parallel for linear(i: step(1), step(2)) // omp52-error {{multiple 'step size' found in linear clause}}
+#else  
 #pragma omp target parallel for linear(i)
+#endif
   for (int k = 0; k < argc; ++k)
     ++k;
 

diff  --git a/clang/test/OpenMP/target_parallel_for_simd_ast_print.cpp b/clang/test/OpenMP/target_parallel_for_simd_ast_print.cpp
index 828ceef0374e1e2..c3b115dafa0912b 100644
--- a/clang/test/OpenMP/target_parallel_for_simd_ast_print.cpp
+++ b/clang/test/OpenMP/target_parallel_for_simd_ast_print.cpp
@@ -7,6 +7,9 @@
 // RUN: %clang_cc1 -verify -fopenmp -ast-print %s -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51
 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s -Wno-openmp-mapping -DOMP51
 // RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -ast-print %s -Wno-openmp-mapping -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -x c++ -std=c++11 -emit-pch -o %t %s -Wno-openmp-mapping -DOMP52
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -Wno-openmp-mapping -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=45 -ast-print %s -Wno-openmp-mapping | FileCheck %s --check-prefix=CHECK --check-prefix=OMP45
 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s -Wno-openmp-mapping
@@ -18,6 +21,10 @@
 // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s -Wno-openmp-mapping -DOMP51
 // RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51
 // expected-no-diagnostics
+// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -ast-print %s -Wno-openmp-mapping -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -x c++ -std=c++11 -emit-pch -o %t %s -Wno-openmp-mapping -DOMP52
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -Wno-openmp-mapping -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
+// expected-no-diagnostics
 
 #ifndef HEADER
 #define HEADER
@@ -131,7 +138,7 @@ T tmain(T argc, T *argv) {
   // CHECK-NEXT: for (T i = 0; i < 2; ++i) {
   // CHECK-NEXT: }
 
-#ifdef OMP51
+#if defined(OMP51) || defined(OMP52)
 #pragma omp target parallel for simd if(target:argc > 0) if (simd: argc) nontemporal(argc, c, d) order(unconstrained:concurrent) allocate(omp_high_bw_mem_alloc:f) private(f) uses_allocators(omp_high_bw_mem_alloc)
 #elif OMP5
 #pragma omp target parallel for simd if(target:argc > 0) if (simd: argc) nontemporal(argc, c, d) order(concurrent) allocate(omp_high_bw_mem_alloc:f) private(f) uses_allocators(omp_high_bw_mem_alloc)
@@ -142,6 +149,7 @@ T tmain(T argc, T *argv) {
   // OMP45: #pragma omp target parallel for simd if(target: argc > 0)
   // OMP50: #pragma omp target parallel for simd if(target: argc > 0) if(simd: argc) nontemporal(argc,c,d) order(concurrent) allocate(omp_high_bw_mem_alloc: f) private(f) uses_allocators(omp_high_bw_mem_alloc)
   // OMP51: #pragma omp target parallel for simd if(target: argc > 0) if(simd: argc) nontemporal(argc,c,d) order(unconstrained: concurrent) allocate(omp_high_bw_mem_alloc: f) private(f) uses_allocators(omp_high_bw_mem_alloc)
+  // OMP52: #pragma omp target parallel for simd if(target: argc > 0) if(simd: argc) nontemporal(argc,c,d) order(unconstrained: concurrent) allocate(omp_high_bw_mem_alloc: f) private(f) uses_allocators(omp_high_bw_mem_alloc)
   // CHECK-NEXT: for (T i = 0; i < 2; ++i) {
   // CHECK-NEXT: }
 
@@ -237,12 +245,15 @@ int main(int argc, char **argv) {
     a = 2;
 // CHECK-NEXT: for (int i = 0; i < 2; ++i)
 // CHECK-NEXT: a = 2;
-
+#ifdef OMP52
+#pragma omp target parallel for simd private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) ordered if (target: argc) num_threads(a) default(shared) shared(e) reduction(+ : h) linear(a: step(-5))
+#else
 #pragma omp target parallel for simd private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) ordered if (target: argc) num_threads(a) default(shared) shared(e) reduction(+ : h) linear(a:-5)
+#endif
   for (int i = 0; i < 10; ++i)
     for (int j = 0; j < 10; ++j)
       foo();
-  // CHECK: #pragma omp target parallel for simd private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) ordered if(target: argc) num_threads(a) default(shared) shared(e) reduction(+: h) linear(a: -5)
+  // CHECK: #pragma omp target parallel for simd private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) ordered if(target: argc) num_threads(a) default(shared) shared(e) reduction(+: h) linear(a: step(-5))
   // CHECK-NEXT: for (int i = 0; i < 10; ++i)
   // CHECK-NEXT: for (int j = 0; j < 10; ++j)
   // CHECK-NEXT: foo();
@@ -265,7 +276,7 @@ int main(int argc, char **argv) {
   // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
   // CHECK-NEXT: }
 
-#ifdef OMP51
+#if defined(OMP51) || defined(OMP52)
 #pragma omp target parallel for simd if (parallel:argc > 0)
 #elif OMP5
 #pragma omp target parallel for simd if (parallel:argc > 0) if(simd: argc)
@@ -276,6 +287,7 @@ int main(int argc, char **argv) {
   // OMP45: #pragma omp target parallel for simd if(parallel: argc > 0)
   // OMP50: #pragma omp target parallel for simd if(parallel: argc > 0) if(simd: argc)
   // OMP51: #pragma omp target parallel for simd if(parallel: argc > 0)
+  // OMP52: #pragma omp target parallel for simd if(parallel: argc > 0)
   // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
   // CHECK-NEXT: }
 

diff  --git a/clang/test/OpenMP/target_parallel_for_simd_linear_messages.cpp b/clang/test/OpenMP/target_parallel_for_simd_linear_messages.cpp
index 36f9f2967b2a914..1da49a9a5e4c400 100644
--- a/clang/test/OpenMP/target_parallel_for_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/target_parallel_for_simd_linear_messages.cpp
@@ -1,6 +1,8 @@
 // RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 #pragma omp requires dynamic_allocators
 
@@ -16,8 +18,8 @@ extern const omp_allocator_handle_t omp_pteam_mem_alloc;
 extern const omp_allocator_handle_t omp_thread_mem_alloc;
 
 void xxx(int argc) {
-  int i, lin, step; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step' to silence this warning}}
-#pragma omp target parallel for simd linear(i, lin : step) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step' is uninitialized when used here}}
+  int i, lin, step_sz; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step_sz' to silence this warning}}
+#pragma omp target parallel for simd linear(i, lin : step_sz) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step_sz' is uninitialized when used here}}
   for (i = 0; i < 10; ++i)
     ;
 }
@@ -272,16 +274,28 @@ int main(int argc, char **argv) {
 #pragma omp target parallel for simd linear(i)
     for (int k = 0; k < argc; ++k)
       ++k;
+#ifdef OMP52
+#pragma omp target parallel for simd linear(i : uval, step(4)) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}}
+#else
 #pragma omp target parallel for simd linear(i : 4)
+#endif
     for (int k = 0; k < argc; ++k) {
       ++k;
       i += 4;
     }
   }
+#ifdef OMP52
+#pragma omp target parallel for simd linear(j: step() //omp52-error 2 {{expected expression}} omp52-error{{expected ')'}} omp52-note{{to match this '('}}
+#else
 #pragma omp target parallel for simd linear(j)
+#endif
   for (int k = 0; k < argc; ++k)
     ++k;
+#ifdef OMP52
+#pragma omp target parallel for simd linear(i: step(1), step(2)) // omp52-error {{multiple 'step size' found in linear clause}}
+#else  
 #pragma omp target parallel for simd linear(i)
+#endif
   for (int k = 0; k < argc; ++k)
     ++k;
 

diff  --git a/clang/test/OpenMP/target_simd_ast_print.cpp b/clang/test/OpenMP/target_simd_ast_print.cpp
index 62f9e380adbd3da..ec9de55392b41b5 100644
--- a/clang/test/OpenMP/target_simd_ast_print.cpp
+++ b/clang/test/OpenMP/target_simd_ast_print.cpp
@@ -7,6 +7,9 @@
 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -ast-print %s -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51
 // RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -x c++ -std=c++11 -emit-pch -o %t %s -Wno-openmp-mapping -DOMP51
 // RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -ast-print %s -Wno-openmp-mapping -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -x c++ -std=c++11 -emit-pch -o %t %s -Wno-openmp-mapping -DOMP52
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -Wno-openmp-mapping -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=45 -ast-print %s -Wno-openmp-mapping | FileCheck %s --check-prefix=CHECK --check-prefix=OMP45
 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s -Wno-openmp-mapping
@@ -18,6 +21,10 @@
 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=51 -x c++ -std=c++11 -emit-pch -o %t %s -Wno-openmp-mapping -DOMP51
 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=51 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51
 // expected-no-diagnostics
+// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -ast-print %s -Wno-openmp-mapping -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -x c++ -std=c++11 -emit-pch -o %t %s -Wno-openmp-mapping -DOMP52
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -Wno-openmp-mapping -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52
+// expected-no-diagnostics
 
 #ifndef HEADER
 #define HEADER
@@ -141,6 +148,7 @@ T tmain(T argc, T *argv) {
   // OMP45: #pragma omp target simd if(target: argc > 0)
   // OMP50: #pragma omp target simd if(target: argc > 0) if(simd: argc) allocate(omp_default_mem_alloc: f) private(f) uses_allocators(omp_default_mem_alloc)
   // OMP51: #pragma omp target simd if(target: argc > 0)
+  // OMP52: #pragma omp target simd if(target: argc > 0)
   // CHECK-NEXT: for (T i = 0; i < 2; ++i) {
   // CHECK-NEXT: }
 
@@ -238,11 +246,15 @@ int main(int argc, char **argv) {
 // CHECK-NEXT: for (int i = 0; i < 2; ++i)
 // CHECK-NEXT: a = 2;
 
+#ifdef OMP52
+#pragma omp target simd private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) if (target: argc) reduction(+ : h) linear(a: step(-5))
+#else
 #pragma omp target simd private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) if (target: argc) reduction(+ : h) linear(a:-5)
+#endif
   for (int i = 0; i < 10; ++i)
     for (int j = 0; j < 10; ++j)
       foo();
-  // CHECK: #pragma omp target simd private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) if(target: argc) reduction(+: h) linear(a: -5)
+  // CHECK: #pragma omp target simd private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) if(target: argc) reduction(+: h) linear(a: step(-5))
   // CHECK-NEXT: for (int i = 0; i < 10; ++i)
   // CHECK-NEXT: for (int j = 0; j < 10; ++j)
   // CHECK-NEXT: foo();
@@ -259,7 +271,7 @@ int main(int argc, char **argv) {
   // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
   // CHECK-NEXT: }
 
-#ifdef OMP51
+#if defined(OMP51) || defined(OMP52)
 #pragma omp target simd if (target:argc > 0) if(simd:argc) nontemporal(argc, c, d) lastprivate(conditional: d, f) order(reproducible:concurrent)
 #elif OMP5
 #pragma omp target simd if (target:argc > 0) if(simd:argc) nontemporal(argc, c, d) lastprivate(conditional: d, f) order(concurrent)
@@ -270,6 +282,7 @@ int main(int argc, char **argv) {
   // OMP45: #pragma omp target simd if(target: argc > 0)
   // OMP50: #pragma omp target simd if(target: argc > 0) if(simd: argc) nontemporal(argc,c,d) lastprivate(conditional: d,f) order(concurrent)
   // OMP51: #pragma omp target simd if(target: argc > 0) if(simd: argc) nontemporal(argc,c,d) lastprivate(conditional: d,f) order(reproducible: concurrent)
+  // OMP52: #pragma omp target simd if(target: argc > 0) if(simd: argc) nontemporal(argc,c,d) lastprivate(conditional: d,f) order(reproducible: concurrent)
   // CHECK-NEXT: for (int i = 0; i < 2; ++i) {
   // CHECK-NEXT: }
 

diff  --git a/clang/test/OpenMP/target_simd_linear_messages.cpp b/clang/test/OpenMP/target_simd_linear_messages.cpp
index 18dde74dbbaa13e..d39d626ea01948b 100644
--- a/clang/test/OpenMP/target_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/target_simd_linear_messages.cpp
@@ -1,6 +1,8 @@
 // RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 #pragma omp requires dynamic_allocators
 typedef void **omp_allocator_handle_t;
@@ -15,8 +17,8 @@ extern const omp_allocator_handle_t omp_pteam_mem_alloc;
 extern const omp_allocator_handle_t omp_thread_mem_alloc;
 
 void xxx(int argc) {
-  int i, lin, step; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step' to silence this warning}}
-#pragma omp target simd linear(i, lin : step) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step' is uninitialized when used here}}
+  int i, lin, step_sz; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step_sz' to silence this warning}}
+#pragma omp target simd linear(i, lin : step_sz) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step_sz' is uninitialized when used here}}
   for (i = 0; i < 10; ++i)
     ;
 }
@@ -271,16 +273,28 @@ int main(int argc, char **argv) {
 #pragma omp target simd linear(i)
     for (int k = 0; k < argc; ++k)
       ++k;
+#ifdef OMP52
+#pragma omp target simd linear(i : uval, step(4)) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}}
+#else
 #pragma omp target simd linear(i : 4)
+#endif
     for (int k = 0; k < argc; ++k) {
       ++k;
       i += 4;
     }
   }
+#ifdef OMP52
+#pragma omp target simd linear(j: step() //omp52-error 2 {{expected expression}} omp52-error{{expected ')'}} omp52-note{{to match this '('}}
+#else
 #pragma omp target simd linear(j)
+#endif
   for (int k = 0; k < argc; ++k)
     ++k;
+#ifdef OMP52
+#pragma omp target simd linear(i: step(1), step(2)) // omp52-error {{multiple 'step size' found in linear clause}}
+#else  
 #pragma omp target simd linear(i)
+#endif
   for (int k = 0; k < argc; ++k)
     ++k;
 

diff  --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp
index 371a7ef4925afa4..7b76fa11d9592d8 100644
--- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp
@@ -1,6 +1,8 @@
 // RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 typedef void **omp_allocator_handle_t;
 extern const omp_allocator_handle_t omp_default_mem_alloc;
@@ -13,8 +15,8 @@ extern const omp_allocator_handle_t omp_pteam_mem_alloc;
 extern const omp_allocator_handle_t omp_thread_mem_alloc;
 
 void xxx(int argc) {
-  int i, step; // expected-note {{initialize the variable 'step' to silence this warning}}
-#pragma omp target teams distribute parallel for simd linear(i : step) // expected-warning {{variable 'step' is uninitialized when used here}}
+  int i, step_sz; // expected-note {{initialize the variable 'step_sz' to silence this warning}}
+#pragma omp target teams distribute parallel for simd linear(i : step_sz) // expected-warning {{variable 'step_sz' is uninitialized when used here}}
   for (i = 0; i < 10; ++i)
     ;
 }

diff  --git a/clang/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp b/clang/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp
index 11c24cbd7c7367e..9a875a4d544d418 100644
--- a/clang/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp
@@ -1,6 +1,8 @@
 // RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 typedef void **omp_allocator_handle_t;
 extern const omp_allocator_handle_t omp_default_mem_alloc;
@@ -13,8 +15,8 @@ extern const omp_allocator_handle_t omp_pteam_mem_alloc;
 extern const omp_allocator_handle_t omp_thread_mem_alloc;
 
 void xxx(int argc) {
-  int i, step; // expected-note {{initialize the variable 'step' to silence this warning}}
-#pragma omp target teams distribute simd linear(i : step) // expected-warning {{variable 'step' is uninitialized when used here}}
+  int i, step_sz; // expected-note {{initialize the variable 'step_sz' to silence this warning}}
+#pragma omp target teams distribute simd linear(i : step_sz) // expected-warning {{variable 'step_sz' is uninitialized when used here}}
   for (i = 0; i < 10; ++i)
     ;
 }

diff  --git a/clang/test/OpenMP/taskloop_simd_linear_messages.cpp b/clang/test/OpenMP/taskloop_simd_linear_messages.cpp
index 4007b139606fc8e..2f9624c65aa7097 100644
--- a/clang/test/OpenMP/taskloop_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/taskloop_simd_linear_messages.cpp
@@ -1,6 +1,8 @@
 // RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 typedef void **omp_allocator_handle_t;
 extern const omp_allocator_handle_t omp_null_allocator;
@@ -14,8 +16,8 @@ extern const omp_allocator_handle_t omp_pteam_mem_alloc;
 extern const omp_allocator_handle_t omp_thread_mem_alloc;
 
 void xxx(int argc) {
-  int i, lin, step; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step' to silence this warning}}
-#pragma omp taskloop simd linear(i, lin : step) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step' is uninitialized when used here}}
+  int i, lin, step_sz; // expected-note {{initialize the variable 'lin' to silence this warning}} expected-note {{initialize the variable 'step_sz' to silence this warning}}
+#pragma omp taskloop simd linear(i, lin : step_sz) // expected-warning {{variable 'lin' is uninitialized when used here}} expected-warning {{variable 'step_sz' is uninitialized when used here}}
   for (i = 0; i < 10; ++i)
     ;
 }
@@ -149,9 +151,16 @@ template<class I, class C> int foomain(I argc, C **argv) {
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp taskloop simd linear (S1) // expected-error {{'S1' does not refer to a value}}
   for (int k = 0; k < argc; ++k) ++k;
+#if defined(OMP52)
+  // omp52-error at +3{{step simple modifier is exclusive and can't be use with 'val', 'uval' or 'ref' modifier}}
+  // expected-error at +2 {{linear variable with incomplete type 'S1'}}
+  // expected-error at +1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
+  #pragma omp taskloop simd linear (a, b: val, B::ib)
+#else
   // expected-error at +2 {{linear variable with incomplete type 'S1'}}
   // expected-error at +1 {{argument of a linear clause should be of integral or pointer type, not 'S2'}}
   #pragma omp taskloop simd linear (val(a, b):B::ib)
+#endif
   for (int k = 0; k < argc; ++k) ++k;
   #pragma omp taskloop simd linear (argv[1]) // expected-error {{expected variable name}}
   for (int k = 0; k < argc; ++k) ++k;
@@ -255,13 +264,35 @@ int main(int argc, char **argv) {
     int i;
     #pragma omp taskloop simd linear(val(i))
     for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+    #pragma omp taskloop simd linear(i : uval, step(4)) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}}
+#else
     #pragma omp taskloop simd linear(uval(i) : 4) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}}
+#endif
     for (int k = 0; k < argc; ++k) { ++k; i += 4; }
   }
+#ifdef OMP52
+  #pragma omp taskloop simd linear(j: ref)
+#else  
   #pragma omp taskloop simd linear(ref(j))
+#endif
   for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+  #pragma omp taskloop simd linear(i: step(1), step(2)) // omp52-error {{multiple 'step size' found in linear clause}}
+#else  
   #pragma omp taskloop simd linear(i)
+#endif
+  for (int k = 0; k < argc; ++k) ++k;
+#ifdef OMP52
+  #pragma omp taskloop simd linear(i: val, val) // omp52-error {{multiple 'linear modifier' found in linear clause}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp taskloop simd linear(j: step()) // omp52-error 2 {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp taskloop simd linear(j: pval) // omp52-error {{use of undeclared identifier 'pval'}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp taskloop simd linear(i: val, step(2 // omp52-error {{expected ')' or ',' after 'step expression'}} omp52-error 2 {{expected ')'}}  omp52-note 2 {{to match this '('}}
   for (int k = 0; k < argc; ++k) ++k;
+#endif
 
   foomain<int,char>(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
   return 0;

diff  --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp
index 1d2b7a73cd69807..8e3864ba5e2a4d2 100644
--- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp
@@ -1,12 +1,14 @@
 // RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 extern int omp_default_mem_alloc;
 void xxx(int argc) {
-  int i, step; // expected-note {{initialize the variable 'step' to silence this warning}}
+  int i, step_sz; // expected-note {{initialize the variable 'step_sz' to silence this warning}}
 #pragma omp target
-#pragma omp teams distribute parallel for simd linear(i : step) // expected-warning {{variable 'step' is uninitialized when used here}}
+#pragma omp teams distribute parallel for simd linear(i : step_sz) // expected-warning {{variable 'step_sz' is uninitialized when used here}}
   for (i = 0; i < 10; ++i)
     ;
 }

diff  --git a/clang/test/OpenMP/teams_distribute_simd_linear_messages.cpp b/clang/test/OpenMP/teams_distribute_simd_linear_messages.cpp
index 6f4592e07cfd512..d6c74eb853a5d9f 100644
--- a/clang/test/OpenMP/teams_distribute_simd_linear_messages.cpp
+++ b/clang/test/OpenMP/teams_distribute_simd_linear_messages.cpp
@@ -1,12 +1,14 @@
 // RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 -DOMP52 %s -Wuninitialized
 
 extern int omp_default_mem_alloc;
 void xxx(int argc) {
-  int i, step; // expected-note {{initialize the variable 'step' to silence this warning}}
+  int i, sz; // expected-note {{initialize the variable 'sz' to silence this warning}}
 #pragma omp target
-#pragma omp teams distribute simd linear(i : step) // expected-warning {{variable 'step' is uninitialized when used here}}
+#pragma omp teams distribute simd linear(i : sz) // expected-warning {{variable 'sz' is uninitialized when used here}}
   for (i = 0; i < 10; ++i)
     ;
 }


        


More information about the cfe-commits mailing list