]> gcc.gnu.org Git - gcc.git/commitdiff
openmp: Add support for OpenMP 5.2 linear clause syntax for C/C++
authorJakub Jelinek <jakub@redhat.com>
Tue, 7 Jun 2022 08:05:08 +0000 (10:05 +0200)
committerJakub Jelinek <jakub@redhat.com>
Tue, 7 Jun 2022 08:05:08 +0000 (10:05 +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.

12 files changed:
gcc/c/c-parser.cc
gcc/c/c-typeck.cc
gcc/cp/parser.cc
gcc/cp/semantics.cc
gcc/fortran/trans-openmp.cc
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 c9a8d145ff9ec42c476497f2f69a8569e43b9416..1704a52be12949acf9ef74211f6f427ff44c789d 100644 (file)
@@ -15668,7 +15668,17 @@ c_parser_omp_clause_allocate (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)
@@ -15676,6 +15686,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))
@@ -15691,6 +15702,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);
        }
@@ -15706,15 +15718,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;
+           }
        }
 
     }
@@ -15725,6 +15817,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 21a93c3665c070707b1fa41ae90b1626c2b6872c..fd0a7f81a7a92461f8939208e77d1d169e075d01 100644 (file)
@@ -14478,11 +14478,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 535bf7eedbbe2438ebdb97982c9baaed8afbe6f7..da2f370cdca55ec7cf13a766681b4846eeed8143 100644 (file)
@@ -38942,7 +38942,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,
@@ -38951,6 +38965,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))
@@ -38968,7 +38983,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;
     }
@@ -38990,10 +39008,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);
@@ -39028,6 +39145,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 3600d270ff8d3e891b071e3a768d311f9e517259..24cca99e9092993767d45ef1f910d0155bcb5feb 100644 (file)
@@ -6827,10 +6827,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 bfd24f964eaf78003420f090f54f668894b2f988..c6a584d36f221cb2ad7de14f44868c2aad74392a 100644 (file)
@@ -2769,6 +2769,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)
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 6acd394a0790ad2ad989f195a3288f0f0a8cc489..bfabe9e76279d7c3383b684ed61cc92228de4500 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 f84958933d51144bb6ce7cc41eca5f7f06814550..507ea252b958b9fb0a5d69c1ddd53edcd746112d 100644 (file)
@@ -1841,6 +1841,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) \
This page took 0.142982 seconds and 5 git commands to generate.