]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
openmp: Add support for OpenMP 5.2 linear clause syntax for C/C++
authorJakub Jelinek <jakub@redhat.com>
Tue, 5 Jul 2022 09:15:15 +0000 (11:15 +0200)
committerTobias Burnus <tobias@codesourcery.com>
Tue, 5 Jul 2022 09:15:15 +0000 (11:15 +0200)
The syntax for linear clause changed in 5.2, the original syntax
which is still valid is:
linear (var1, var2)
linear (var3, var4 : step1)
The 4.5 syntax with modifiers like:
linear (val (var5, var6))
linear (val (var7, var8) : step2)
is still supported in 5.2, but is deprecated there.
Instead, one can use a new syntax:
linear (var9, var10 : val)
linear (var11, var12 : step (step3), val)
As val, ref, uval or step (someexpr) can be valid expressions (and especially
in C++ can be const / constexpr / consteval), the spec says that
when the whole step expression is val (or ref or uval) or step ( ... )
then it is the new modifier syntax, one can use + 0 or 0 + or 1 * or * 1
or ()s to say it is the old step expression.
Also, 5.2 now allows val modifier to be specified even outside of declare simd
(but not the other modifiers).  I've implemented this for the new modifier
syntax only, the old one keeps the old restriction (which is why
OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER flag has been introduced).

2022-06-07  Jakub Jelinek  <jakub@redhat.com>

gcc/
* tree.h (OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER): Define.
* tree-pretty-print.cc (dump_omp_clause) <case OMP_CLAUSE_LINEAR>:
Adjust clause printing style depending on
OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER.
gcc/c/
* c-parser.cc (c_parser_omp_clause_linear): Parse OpenMP 5.2
style linear clause modifiers.  Set
OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER flag on the clauses when
old style modifiers are used.
* c-typeck.cc (c_finish_omp_clauses): Only reject linear clause
with val modifier on simd or for if the old style modifiers are
used.
gcc/cp/
* parser.cc (cp_parser_omp_clause_linear): Parse OpenMP 5.2
style linear clause modifiers.  Set
OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER flag on the clauses when
old style modifiers are used.
* semantics.cc (finish_omp_clauses): Only reject linear clause
with val modifier on simd or for if the old style modifiers are
used.
gcc/fortran/
* trans-openmp.cc (gfc_trans_omp_clauses): Set
OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER on OMP_CLAUSE_LINEAR
clauses unconditionally for now.
gcc/testsuite/
* c-c++-common/gomp/linear-2.c: New test.
* c-c++-common/gomp/linear-3.c: New test.
* g++.dg/gomp/linear-3.C: New test.
* g++.dg/gomp/linear-4.C: New test.
* g++.dg/gomp/linear-5.C: New test.

(cherry picked from commit 03b71406323ddc065b1d7837d8b43b17e4b048b5)

17 files changed:
gcc/ChangeLog.omp
gcc/c/ChangeLog.omp
gcc/c/c-parser.cc
gcc/c/c-typeck.cc
gcc/cp/ChangeLog.omp
gcc/cp/parser.cc
gcc/cp/semantics.cc
gcc/fortran/ChangeLog.omp
gcc/fortran/trans-openmp.cc
gcc/testsuite/ChangeLog.omp
gcc/testsuite/c-c++-common/gomp/linear-2.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/gomp/linear-3.c [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/linear-3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/linear-4.C [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/linear-5.C [new file with mode: 0644]
gcc/tree-pretty-print.cc
gcc/tree.h

index 161e5f89be8225d18f63e0e0b7d7a49e0f46f438..800b902fcb2a2ddf33cb3083768f3cba48f9379d 100644 (file)
@@ -1,3 +1,13 @@
+2022-07-05  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backport from mainline:
+       2022-06-07  Jakub Jelinek  <jakub@redhat.com>
+
+       * tree.h (OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER): Define.
+       * tree-pretty-print.cc (dump_omp_clause) <case OMP_CLAUSE_LINEAR>:
+       Adjust clause printing style depending on
+       OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER.
+
 2022-07-05  Tobias Burnus  <tobias@codesourcery.com>
 
        Backport from mainline:
index 10499527eb7cefefbadb9fcf31bdbad7913fc2cd..7d8a171a2f4fdde24b4ace45d0bb7a4b78100a94 100644 (file)
@@ -1,3 +1,16 @@
+2022-07-05  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backport from mainline:
+       2022-06-07  Jakub Jelinek  <jakub@redhat.com>
+
+       * c-parser.cc (c_parser_omp_clause_linear): Parse OpenMP 5.2
+       style linear clause modifiers.  Set
+       OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER flag on the clauses when
+       old style modifiers are used.
+       * c-typeck.cc (c_finish_omp_clauses): Only reject linear clause
+       with val modifier on simd or for if the old style modifiers are
+       used.
+
 2022-07-05  Tobias Burnus  <tobias@codesourcery.com>
 
        Backport from mainline:
index a6a576930c16fd097c91dcb4ced70358bbf92ffe..5a6bf797283a6a872bfd40716218d51f160b7b28 100644 (file)
@@ -15903,7 +15903,17 @@ c_parser_omp_clause_uses_allocators (c_parser *parser, tree list)
 
    OpenMP 4.5:
    linear ( modifier ( variable-list ) )
-   linear ( modifier ( variable-list ) : expression ) */
+   linear ( modifier ( variable-list ) : expression )
+
+   modifier:
+     val
+
+   OpenMP 5.2:
+   linear ( variable-list : modifiers-list )
+
+   modifiers:
+     val
+     step ( expression )  */
 
 static tree
 c_parser_omp_clause_linear (c_parser *parser, tree list)
@@ -15911,6 +15921,7 @@ c_parser_omp_clause_linear (c_parser *parser, tree list)
   location_t clause_loc = c_parser_peek_token (parser)->location;
   tree nl, c, step;
   enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
+  bool old_linear_modifier = false;
 
   matching_parens parens;
   if (!parens.require_open (parser))
@@ -15926,6 +15937,7 @@ c_parser_omp_clause_linear (c_parser *parser, tree list)
        kind = OMP_CLAUSE_LINEAR_DEFAULT;
       if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
        {
+         old_linear_modifier = true;
          c_parser_consume_token (parser);
          c_parser_consume_token (parser);
        }
@@ -15941,15 +15953,95 @@ c_parser_omp_clause_linear (c_parser *parser, tree list)
     {
       c_parser_consume_token (parser);
       location_t expr_loc = c_parser_peek_token (parser)->location;
-      c_expr expr = c_parser_expr_no_commas (parser, NULL);
-      expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
-      step = expr.value;
-      step = c_fully_fold (step, false, NULL);
-      if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
+      bool has_modifiers = false;
+      if (kind == OMP_CLAUSE_LINEAR_DEFAULT
+         && c_parser_next_token_is (parser, CPP_NAME))
+       {
+         c_token *tok = c_parser_peek_token (parser);
+         const char *p = IDENTIFIER_POINTER (tok->value);
+         unsigned int pos = 0;
+         if (strcmp ("val", p) == 0)
+           pos = 2;
+         else if (strcmp ("step", p) == 0
+                  && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
+           {
+             pos = 3;
+             if (c_parser_check_balanced_raw_token_sequence (parser, &pos)
+                 && (c_parser_peek_nth_token_raw (parser, pos)->type
+                     == CPP_CLOSE_PAREN))
+               ++pos;
+             else
+               pos = 0;
+           }
+         if (pos)
+           {
+             tok = c_parser_peek_nth_token_raw (parser, pos);
+             if (tok->type == CPP_COMMA || tok->type == CPP_CLOSE_PAREN)
+               has_modifiers = true;
+           }
+       }
+      if (has_modifiers)
+       {
+         step = NULL_TREE;
+         while (c_parser_next_token_is (parser, CPP_NAME))
+           {
+             c_token *tok = c_parser_peek_token (parser);
+             const char *p = IDENTIFIER_POINTER (tok->value);
+             if (strcmp ("val", p) == 0)
+               {
+                 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
+                   error_at (tok->location, "multiple linear modifiers");
+                 kind = OMP_CLAUSE_LINEAR_DEFAULT;
+                 c_parser_consume_token (parser);
+               }
+             else if (strcmp ("step", p) == 0)
+               {
+                 c_parser_consume_token (parser);
+                 matching_parens parens2;
+                 if (parens2.require_open (parser))
+                   {
+                     if (step)
+                       error_at (tok->location,
+                                 "multiple %<step%> modifiers");
+                     expr_loc = c_parser_peek_token (parser)->location;
+                     c_expr expr = c_parser_expr_no_commas (parser, NULL);
+                     expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
+                                                      true);
+                     step = c_fully_fold (expr.value, false, NULL);
+                     if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
+                       {
+                         error_at (clause_loc, "%<linear%> clause step "
+                                               "expression must be integral");
+                         step = integer_one_node;
+                       }
+                     parens2.skip_until_found_close (parser);
+                   }
+                 else
+                   break;
+               }
+             else
+               break;
+             if (c_parser_next_token_is (parser, CPP_COMMA))
+               {
+                 c_parser_consume_token (parser);
+                 continue;
+               }
+             break;
+           }
+         if (!step)
+           step = integer_one_node;
+       }
+      else
        {
-         error_at (clause_loc, "%<linear%> clause step expression must "
-                               "be integral");
-         step = integer_one_node;
+         c_expr expr = c_parser_expr_no_commas (parser, NULL);
+         expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
+         step = c_fully_fold (expr.value, false, NULL);
+         if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
+           {
+             error_at (clause_loc, "%<linear%> clause step expression must "
+                                   "be integral");
+             step = integer_one_node;
+           }
        }
 
     }
@@ -15960,6 +16052,7 @@ c_parser_omp_clause_linear (c_parser *parser, tree list)
     {
       OMP_CLAUSE_LINEAR_STEP (c) = step;
       OMP_CLAUSE_LINEAR_KIND (c) = kind;
+      OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c) = old_linear_modifier;
     }
 
   parens.skip_until_found_close (parser);
index 4623b9d392f0ccb6a88579b890d75d9fe92e1e50..d336308167b9dc42309faa5b20173ae8d6c027b3 100644 (file)
@@ -14547,11 +14547,13 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
            need_implicitly_determined = true;
          t = OMP_CLAUSE_DECL (c);
          if (ort != C_ORT_OMP_DECLARE_SIMD
-             && OMP_CLAUSE_LINEAR_KIND (c) != OMP_CLAUSE_LINEAR_DEFAULT)
+             && OMP_CLAUSE_LINEAR_KIND (c) != OMP_CLAUSE_LINEAR_DEFAULT
+             && OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c))
            {
              error_at (OMP_CLAUSE_LOCATION (c),
                        "modifier should not be specified in %<linear%> "
-                       "clause on %<simd%> or %<for%> constructs");
+                       "clause on %<simd%> or %<for%> constructs when not "
+                       "using OpenMP 5.2 modifiers");
              OMP_CLAUSE_LINEAR_KIND (c) = OMP_CLAUSE_LINEAR_DEFAULT;
            }
          if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
index bd4a83a376d168a42f4984786462d9ecc0756281..0943c08f3ccfa96acf10e7777b06069fb7ea0083 100644 (file)
@@ -1,3 +1,16 @@
+2022-07-05  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backport from mainline:
+       2022-06-07  Jakub Jelinek  <jakub@redhat.com>
+
+       * parser.cc (cp_parser_omp_clause_linear): Parse OpenMP 5.2
+       style linear clause modifiers.  Set
+       OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER flag on the clauses when
+       old style modifiers are used.
+       * semantics.cc (finish_omp_clauses): Only reject linear clause
+       with val modifier on simd or for if the old style modifiers are
+       used.
+
 2022-07-05  Tobias Burnus  <tobias@codesourcery.com>
 
        Backport from mainline:
index 5620cf626d19d4315ce052f375c9de9e832d6c07..b744033364c8c04f6e4b00f974781deffd39f757 100644 (file)
@@ -39055,7 +39055,21 @@ cp_parser_omp_clause_lastprivate (cp_parser *parser, tree list)
 
    OpenMP 4.5:
    linear ( modifier ( variable-list ) )
-   linear ( modifier ( variable-list ) : expression ) */
+   linear ( modifier ( variable-list ) : expression )
+
+   modifier:
+     val
+     ref
+     uval
+
+   OpenMP 5.2:
+   linear ( variable-list : modifiers-list )
+
+   modifiers:
+     val
+     ref
+     uval
+     step ( expression )  */
 
 static tree
 cp_parser_omp_clause_linear (cp_parser *parser, tree list,
@@ -39064,6 +39078,7 @@ cp_parser_omp_clause_linear (cp_parser *parser, tree list,
   tree nlist, c, step = integer_one_node;
   bool colon;
   enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
+  bool old_linear_modifier = false;
 
   matching_parens parens;
   if (!parens.require_open (parser))
@@ -39081,7 +39096,10 @@ cp_parser_omp_clause_linear (cp_parser *parser, tree list,
       else if (strcmp ("uval", p) == 0)
        kind = OMP_CLAUSE_LINEAR_UVAL;
       if (cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN))
-       cp_lexer_consume_token (parser->lexer);
+       {
+         cp_lexer_consume_token (parser->lexer);
+         old_linear_modifier = true;
+       }
       else
        kind = OMP_CLAUSE_LINEAR_DEFAULT;
     }
@@ -39103,10 +39121,109 @@ cp_parser_omp_clause_linear (cp_parser *parser, tree list,
 
   if (colon)
     {
+      bool has_modifiers = false;
+      if (kind == OMP_CLAUSE_LINEAR_DEFAULT
+         && cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+       {
+         tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+         const char *p = IDENTIFIER_POINTER (id);
+         size_t pos = 0;
+         if (strcmp ("ref", p) == 0
+             || strcmp ("val", p) == 0
+             || strcmp ("uval", p) == 0)
+           pos = 2;
+         else if (strcmp ("step", p) == 0
+                  && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN))
+           {
+             pos = cp_parser_skip_balanced_tokens (parser, 2);
+             if (pos == 2)
+               pos = 0;
+           }
+         if (pos != 0
+             && (cp_lexer_nth_token_is (parser->lexer, pos, CPP_COMMA)
+                 || cp_lexer_nth_token_is (parser->lexer, pos,
+                                           CPP_CLOSE_PAREN)))
+           has_modifiers = true;
+       }
+
       step = NULL_TREE;
-      if (declare_simd
-         && cp_lexer_next_token_is (parser->lexer, CPP_NAME)
-         && cp_lexer_nth_token_is (parser->lexer, 2, CPP_CLOSE_PAREN))
+      if (has_modifiers)
+       {
+         while (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+           {
+             tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+             const char *p = IDENTIFIER_POINTER (id);
+             enum omp_clause_linear_kind nkind = OMP_CLAUSE_LINEAR_DEFAULT;
+             if (strcmp ("ref", p) == 0)
+               nkind = OMP_CLAUSE_LINEAR_REF;
+             else if (strcmp ("val", p) == 0)
+               nkind = OMP_CLAUSE_LINEAR_VAL;
+             else if (strcmp ("uval", p) == 0)
+               nkind = OMP_CLAUSE_LINEAR_UVAL;
+             if (nkind != OMP_CLAUSE_LINEAR_DEFAULT)
+               {
+                 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
+                   error_at (cp_lexer_peek_token (parser->lexer)->location,
+                             "multiple linear modifiers");
+                 kind = nkind;
+                 cp_lexer_consume_token (parser->lexer);
+               }
+             else if (strcmp ("step", p) == 0)
+               {
+                 location_t step_loc
+                   = cp_lexer_peek_token (parser->lexer)->location;
+                 cp_lexer_consume_token (parser->lexer);
+                 matching_parens parens2;
+                 if (parens2.require_open (parser))
+                   {
+                     if (step)
+                       error_at (step_loc, "multiple %<step%> modifiers");
+                     if (declare_simd
+                         && cp_lexer_next_token_is (parser->lexer, CPP_NAME)
+                         && cp_lexer_nth_token_is (parser->lexer, 2,
+                                                   CPP_CLOSE_PAREN))
+                       {
+                         cp_token *token
+                           = cp_lexer_peek_token (parser->lexer);
+                         location_t tok_loc = token->location;
+                         cp_parser_parse_tentatively (parser);
+                         step = cp_parser_id_expression (parser, false, true,
+                                                         NULL, false, false);
+                         if (step != error_mark_node)
+                           step = cp_parser_lookup_name_simple (parser, step,
+                                                                tok_loc);
+                         if (step == error_mark_node)
+                           {
+                             step = NULL_TREE;
+                             cp_parser_abort_tentative_parse (parser);
+                           }
+                         else if (!cp_parser_parse_definitely (parser))
+                           step = NULL_TREE;
+                       }
+                     if (!step)
+                       step = cp_parser_assignment_expression (parser);
+                     if (!parens2.require_close (parser))
+                       cp_parser_skip_to_closing_parenthesis (parser, true,
+                                                              false, true);
+                   }
+                 else
+                   break;
+               }
+             else
+               break;
+             if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+               {
+                 cp_lexer_consume_token (parser->lexer);
+                 continue;
+               }
+             break;
+           }
+         if (!step)
+           step = integer_one_node;
+       }
+      else if (declare_simd
+              && cp_lexer_next_token_is (parser->lexer, CPP_NAME)
+              && cp_lexer_nth_token_is (parser->lexer, 2, CPP_CLOSE_PAREN))
        {
          cp_token *token = cp_lexer_peek_token (parser->lexer);
          cp_parser_parse_tentatively (parser);
@@ -39141,6 +39258,7 @@ cp_parser_omp_clause_linear (cp_parser *parser, tree list,
     {
       OMP_CLAUSE_LINEAR_STEP (c) = step;
       OMP_CLAUSE_LINEAR_KIND (c) = kind;
+      OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c) = old_linear_modifier;
     }
 
   return nlist;
index 2b84e0004870c69c983a5115a598460b0449bf25..ea3b1db027cbc138fda775ab399fc2dab41dc39f 100644 (file)
@@ -6895,10 +6895,22 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
          if (ort != C_ORT_OMP_DECLARE_SIMD
              && OMP_CLAUSE_LINEAR_KIND (c) != OMP_CLAUSE_LINEAR_DEFAULT)
            {
-             error_at (OMP_CLAUSE_LOCATION (c),
-                       "modifier should not be specified in %<linear%> "
-                       "clause on %<simd%> or %<for%> constructs");
-             OMP_CLAUSE_LINEAR_KIND (c) = OMP_CLAUSE_LINEAR_DEFAULT;
+             if (OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c))
+               {
+                 error_at (OMP_CLAUSE_LOCATION (c),
+                           "modifier should not be specified in %<linear%> "
+                           "clause on %<simd%> or %<for%> constructs when "
+                           "not using OpenMP 5.2 modifiers");
+                 OMP_CLAUSE_LINEAR_KIND (c) = OMP_CLAUSE_LINEAR_DEFAULT;
+               }
+             else if (OMP_CLAUSE_LINEAR_KIND (c) != OMP_CLAUSE_LINEAR_VAL)
+               {
+                 error_at (OMP_CLAUSE_LOCATION (c),
+                           "modifier other than %<val%> specified in "
+                           "%<linear%> clause on %<simd%> or %<for%> "
+                           "constructs when using OpenMP 5.2 modifiers");
+                 OMP_CLAUSE_LINEAR_KIND (c) = OMP_CLAUSE_LINEAR_DEFAULT;
+               }
            }
          if ((VAR_P (t) || TREE_CODE (t) == PARM_DECL)
              && !type_dependent_expression_p (t))
index 730308d9b727a644d53d4731a6e889d1fc8e2e15..39d2143b0cfcb34a872eef59bbfb836839732364 100644 (file)
@@ -1,3 +1,12 @@
+2022-07-05  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backport from mainline:
+       2022-06-07  Jakub Jelinek  <jakub@redhat.com>
+
+       * trans-openmp.cc (gfc_trans_omp_clauses): Set
+       OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER on OMP_CLAUSE_LINEAR
+       clauses unconditionally for now.
+
 2022-07-05  Tobias Burnus  <tobias@codesourcery.com>
 
        Backport from mainline:
index 8d6c017714da6faa55081094a31ab655ef35d083..08c287ae6c2b986feb22d3a82dad3095878e7acd 100644 (file)
@@ -4164,6 +4164,7 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
                            gcc_unreachable ();
                          }
                        OMP_CLAUSE_LINEAR_KIND (node) = kind;
+                       OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (node) = 1;
                        if (last_step_expr && last_step == NULL_TREE)
                          {
                            if (!declare_simd)
index f7f200021c7e14afde469715b028c068931ea593..bec3740ca7db4f93597ea21bf23611385ff3781c 100644 (file)
@@ -1,3 +1,14 @@
+2022-07-05  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backport from mainline:
+       2022-06-07  Jakub Jelinek  <jakub@redhat.com>
+
+       * c-c++-common/gomp/linear-2.c: New test.
+       * c-c++-common/gomp/linear-3.c: New test.
+       * g++.dg/gomp/linear-3.C: New test.
+       * g++.dg/gomp/linear-4.C: New test.
+       * g++.dg/gomp/linear-5.C: New test.
+
 2022-07-05  Tobias Burnus  <tobias@codesourcery.com>
 
        Backport from mainline:
diff --git a/gcc/testsuite/c-c++-common/gomp/linear-2.c b/gcc/testsuite/c-c++-common/gomp/linear-2.c
new file mode 100644 (file)
index 0000000..545b7e5
--- /dev/null
@@ -0,0 +1,58 @@
+/* { dg-do compile } */
+/* { dg-options "-fopenmp" } */
+
+int i;
+
+#pragma omp declare simd linear (x : val, step (1)) linear (y : step (2))
+int bar (int x, int y, int z);
+#pragma omp declare simd linear (x : step (1), val)
+int baz (int x, int y, int z);
+#pragma omp declare simd linear (val (x) : val) uniform (val)
+int qux (int x, int val);
+#pragma omp declare simd linear (x : val, step (val)) uniform (val)
+int corge (int x, int val);
+#pragma omp declare simd linear (x : val)
+int grault (int x);
+int step (int);
+
+void
+foo (int x, int y)
+{
+  int val = 1;
+  #pragma omp simd linear (i: step (3))
+  for (i = 0; i < 33; i += 3)
+    ;
+  #pragma omp simd linear (i: val, step (3))
+  for (i = 0; i < 33; i += 3)
+    ;
+  #pragma omp simd linear (x: step (y + 1))
+  for (i = 0; i < 10; i++)
+    x += y + 1;
+  #pragma omp simd linear (x: step (y + 1), val)
+  for (i = 0; i < 10; i++)
+    x += y + 1;
+  #pragma omp parallel for linear (x: step (y + 1))
+  for (i = 0; i < 10; i++)
+    x += y + 1;
+  #pragma omp parallel for linear (x: val, step (y + 1))
+  for (i = 0; i < 10; i++)
+    x += y + 1;
+  #pragma omp parallel for simd linear (i: step (3))
+  for (i = 0; i < 33; i += 3)
+    ;
+  #pragma omp parallel for simd linear (i: step (3), val)
+  for (i = 0; i < 33; i += 3)
+    ;
+  #pragma omp parallel for simd linear (x: step (y + 1))
+  for (i = 0; i < 10; i++)
+    x += y + 1;
+  #pragma omp parallel for simd linear (x: val, step (y + 1))
+  for (i = 0; i < 10; i++)
+    x += y + 1;
+  #pragma omp parallel for simd linear (i: val + 0)
+  for (i = 0; i < 10; i++)
+    ;
+  #pragma omp parallel for simd linear (i: step (1) * 1)
+  for (i = 0; i < 10; i++)
+    ;
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/linear-3.c b/gcc/testsuite/c-c++-common/gomp/linear-3.c
new file mode 100644 (file)
index 0000000..32fa0bc
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-fopenmp" } */
+
+int step (int);
+int val;
+#pragma omp declare simd linear (val (x) : step (1))   /* { dg-error "is neither constant nor a parameter" } */
+int bar (int x, int y, int z);
+#pragma omp declare simd linear (val (x) : val)                /* { dg-error "is neither constant nor a parameter" } */
+int baz (int x, int y, int z);
diff --git a/gcc/testsuite/g++.dg/gomp/linear-3.C b/gcc/testsuite/g++.dg/gomp/linear-3.C
new file mode 100644 (file)
index 0000000..0936cf8
--- /dev/null
@@ -0,0 +1,54 @@
+// { dg-do compile { target c++11 } }
+// { dg-options "-fopenmp" }
+
+int i;
+
+#pragma omp declare simd linear (x : ref, step (1)) linear (y : step (2), uval)
+int bar (int &x, int &y, int z);
+#pragma omp declare simd linear (x : step (1), uval)
+int baz (int &x, int y, int z);
+#pragma omp declare simd linear (ref (x) : ref) uniform (ref)
+int qux (int &x, int ref);
+#pragma omp declare simd linear (x : ref, step (ref)) uniform (ref)
+int corge (int &x, int ref);
+#pragma omp declare simd linear (x : ref)
+int grault (int &x);
+#pragma omp declare simd linear (x : uval)
+int waldo (int &x);
+constexpr int step (int x) { return x; }
+
+void
+foo (int &x, int &y)
+{
+  #pragma omp simd linear (x: step (y + 1))
+  for (i = 0; i < 10; i++)
+    x += y + 1;
+  #pragma omp simd linear (x: val, step (y + 1))
+  for (i = 0; i < 10; i++)
+    x += y + 1;
+  #pragma omp parallel for linear (x: step (y + 1))
+  for (i = 0; i < 10; i++)
+    x += y + 1;
+  #pragma omp parallel for linear (x: step (y + 1), val)
+  for (i = 0; i < 10; i++)
+    x += y + 1;
+  #pragma omp parallel for simd linear (x: step (y + 1))
+  for (i = 0; i < 10; i++)
+    x += y + 1;
+  #pragma omp parallel for simd linear (x: val, step (y + 1))
+  for (i = 0; i < 10; i++)
+    x += y + 1;
+  #pragma omp parallel for simd linear (x: step (1) + 0)
+  for (i = 0; i < 10; i++)
+    x += step (1) + 0;
+  {
+    constexpr int ref = 1;
+    constexpr int uval = 2;
+    #pragma omp parallel for simd linear (x: ref + 0)
+    for (i = 0; i < 10; i++)
+      x += ref + 0;
+    #pragma omp parallel for simd linear (x: uval * 1)
+    for (i = 0; i < 10; i++)
+      x += uval;
+  }
+}
diff --git a/gcc/testsuite/g++.dg/gomp/linear-4.C b/gcc/testsuite/g++.dg/gomp/linear-4.C
new file mode 100644 (file)
index 0000000..a1b9472
--- /dev/null
@@ -0,0 +1,27 @@
+// { dg-do compile }
+// { dg-options "-fopenmp" }
+
+int i;
+
+void
+foo (int &x, int &y)
+{
+  #pragma omp simd linear (x: step (y + 1), ref)               // { dg-error "modifier other than 'val' specified in 'linear' clause" }
+  for (i = 0; i < 10; i++)
+    x += y + 1;
+  #pragma omp simd linear (x: uval, step (y + 1))              // { dg-error "modifier other than 'val' specified in 'linear' clause" }
+  for (i = 0; i < 10; i++)
+    x += y + 1;
+  #pragma omp parallel for linear (x: ref, step (y + 1))       // { dg-error "modifier other than 'val' specified in 'linear' clause" }
+  for (i = 0; i < 10; i++)
+    x += y + 1;
+  #pragma omp parallel for linear (x: step (y + 1), uval)      // { dg-error "modifier other than 'val' specified in 'linear' clause" }
+  for (i = 0; i < 10; i++)
+    x += y + 1;
+  #pragma omp parallel for simd linear (x: step (y + 1), ref)  // { dg-error "modifier other than 'val' specified in 'linear' clause" }
+  for (i = 0; i < 10; i++)
+    x += y + 1;
+  #pragma omp parallel for simd linear (x: uval, step (y + 1)) // { dg-error "modifier other than 'val' specified in 'linear' clause" }
+  for (i = 0; i < 10; i++)
+    x += y + 1;
+}
diff --git a/gcc/testsuite/g++.dg/gomp/linear-5.C b/gcc/testsuite/g++.dg/gomp/linear-5.C
new file mode 100644 (file)
index 0000000..fbc193e
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile { target c++11 } } */
+/* { dg-options "-fopenmp" } */
+
+constexpr int step (int x) { return x; }
+constexpr int val = 1;
+constexpr int ref = 2;
+constexpr int uval = 3;
+#pragma omp declare simd linear (val (x) : step (1)) linear (ref (y) : step (2)) linear (uval (z) : step (3))
+int foo (int x, int &y, int &z);
+#pragma omp declare simd linear (val (x) : val) linear (ref (y) : ref) linear (uval (z) : uval)
+int bar (int x, int &y, int &z);
+#pragma omp declare simd linear (val (x) : ref) linear (ref (y) : uval) linear (uval (z) : val)
+int baz (int x, int &y, int &z);
+#pragma omp declare simd linear (val (x) : uval) linear (ref (y) : val) linear (uval (z) : ref)
+int qux (int x, int &y, int &z);
index f7b10cf6a5c669422c129042246d3bc383fe8855..8950ea884926bd49c737dfdc328cff899402f6a4 100644 (file)
@@ -707,29 +707,50 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags)
 
     case OMP_CLAUSE_LINEAR:
       pp_string (pp, "linear(");
-      switch (OMP_CLAUSE_LINEAR_KIND (clause))
-       {
-       case OMP_CLAUSE_LINEAR_DEFAULT:
-         break;
-       case OMP_CLAUSE_LINEAR_REF:
-         pp_string (pp, "ref(");
-         break;
-       case OMP_CLAUSE_LINEAR_VAL:
-         pp_string (pp, "val(");
-         break;
-       case OMP_CLAUSE_LINEAR_UVAL:
-         pp_string (pp, "uval(");
-         break;
-       default:
-         gcc_unreachable ();
-       }
+      if (OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (clause))
+       switch (OMP_CLAUSE_LINEAR_KIND (clause))
+         {
+         case OMP_CLAUSE_LINEAR_DEFAULT:
+           break;
+         case OMP_CLAUSE_LINEAR_REF:
+           pp_string (pp, "ref(");
+           break;
+         case OMP_CLAUSE_LINEAR_VAL:
+           pp_string (pp, "val(");
+           break;
+         case OMP_CLAUSE_LINEAR_UVAL:
+           pp_string (pp, "uval(");
+           break;
+         default:
+           gcc_unreachable ();
+         }
       dump_generic_node (pp, OMP_CLAUSE_DECL (clause),
                         spc, flags, false);
-      if (OMP_CLAUSE_LINEAR_KIND (clause) != OMP_CLAUSE_LINEAR_DEFAULT)
+      if (OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (clause)
+         && OMP_CLAUSE_LINEAR_KIND (clause) != OMP_CLAUSE_LINEAR_DEFAULT)
        pp_right_paren (pp);
       pp_colon (pp);
+      if (!OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (clause)
+         && OMP_CLAUSE_LINEAR_KIND (clause) != OMP_CLAUSE_LINEAR_DEFAULT)
+       switch (OMP_CLAUSE_LINEAR_KIND (clause))
+         {
+           case OMP_CLAUSE_LINEAR_REF:
+             pp_string (pp, "ref,step(");
+             break;
+           case OMP_CLAUSE_LINEAR_VAL:
+             pp_string (pp, "val,step(");
+             break;
+           case OMP_CLAUSE_LINEAR_UVAL:
+             pp_string (pp, "uval,step(");
+             break;
+           default:
+             gcc_unreachable ();
+         }
       dump_generic_node (pp, OMP_CLAUSE_LINEAR_STEP (clause),
                         spc, flags, false);
+      if (!OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (clause)
+         && OMP_CLAUSE_LINEAR_KIND (clause) != OMP_CLAUSE_LINEAR_DEFAULT)
+       pp_right_paren (pp);
       pp_right_paren (pp);
       break;
 
index 1b9caf062953ddb4e254450af991f11209a1ce8e..8d855b3b4745ebadb190b861698917a7302d4714 100644 (file)
@@ -1807,6 +1807,11 @@ class auto_suppress_location_wrappers
 #define OMP_CLAUSE_LINEAR_VARIABLE_STRIDE(NODE) \
   TREE_PROTECTED (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LINEAR))
 
+/* True for a LINEAR clause with old style modifier syntax
+   linear(modifier(list)) or linear(modifier(list):step).  */
+#define OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER(NODE) \
+  (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LINEAR)->base.addressable_flag)
+
 /* True if a LINEAR clause is for an array or allocatable variable that
    needs special handling by the frontend.  */
 #define OMP_CLAUSE_LINEAR_ARRAY(NODE) \