Hi!

The latest spec proposals change the meaning of the ordered(n) clause
if collapse > 1 to count the number of source loops.
The ordered >= collapse requirement is something I'm pushing for even when
it is not in the spec (yet).
And, finally, another proposed change is that the + or - signs in the sink:
vector are significant (primarily for unsigned iterators).

Tested on x86_64-linux, committed to gomp-4_1-branch.

2015-09-25  Jakub Jelinek  <ja...@redhat.com>

        * tree.h (OMP_CLAUSE_DEPEND_SINK_NEGATIVE): Define.
        * omp-low.c (extract_omp_for_data, expand_omp_for_init_counts,
        expand_omp_ordered_source, expand_omp_ordered_sink,
        expand_omp_for_ordered_loops, expand_omp_for_generic): Adjust
        for fd->ordered being newly 0 when it used to be 0 before,
        but otherwise being equal to fd->collapse - 1 + old fd->ordered.
        expand_omp_ordered_source_sink): Likewise.  Warn for lexically
        later iteration sink, or for sink on iteration never in iteration
        space.  Use OMP_CLAUSE_DEPEND_SINK_NEGATIVE.
        (lower_depend_clauses): Assert not seeing sink/source depend kinds.
        * tree-pretty-print.c (dump_omp_clause): Use
        OMP_CLAUSE_DEPEND_SINK_NEGATIVE for the +/- sign of sink vector
        constants.
gcc/c/
        * c-parser.c (c_parser_omp_clause_depend_sink): Put - sign
        into OMP_CLAUSE_DEPEND_SINK_NEGATIVE instead of negating the number.
        (c_parser_omp_for_loop): Adjust for ordered clause counting
        source loops before collapsing instead of after it.  Require
        ordered clause parameter to be >= collapse parameter.
gcc/cp/
        * parser.c (cp_parser_omp_clause_depend_sink): Put - sign
        into OMP_CLAUSE_DEPEND_SINK_NEGATIVE instead of negating the number.
        (cp_parser_omp_for_loop): Adjust for ordered clause counting
        source loops before collapsing instead of after it.  Require
        ordered clause parameter to be >= collapse parameter.
        * pt.c (tsubst_omp_clause_decl): Copy
        OMP_CLAUSE_DEPEND_SINK_NEGATIVE flag.
gcc/testsuite/
        * c-c++-common/gomp/sink-1.c (foo): Adjust for new meaning of
        ordered clause on collapse > 1 loops.
        * gcc.dg/gomp/sink-fold-2.c (funk): Remove xfails and adjust
        for new diagnostics wording and only warnings, no errors.
libgomp/
        * testsuite/libgomp.c/doacross-1.c (main): Adjust for new meaning of
        ordered clause on collapse > 1 loops.

--- gcc/tree.h.jj       2015-09-03 16:36:19.000000000 +0200
+++ gcc/tree.h  2015-09-25 13:40:16.739807842 +0200
@@ -1446,6 +1446,9 @@ extern void protected_set_expr_location
 #define OMP_CLAUSE_DEPEND_KIND(NODE) \
   (OMP_CLAUSE_SUBCODE_CHECK (NODE, 
OMP_CLAUSE_DEPEND)->omp_clause.subcode.depend_kind)
 
+#define OMP_CLAUSE_DEPEND_SINK_NEGATIVE(NODE) \
+  TREE_PUBLIC (TREE_LIST_CHECK (NODE))
+
 #define OMP_CLAUSE_MAP_KIND(NODE) \
   ((enum gomp_map_kind) OMP_CLAUSE_SUBCODE_CHECK (NODE, 
OMP_CLAUSE_MAP)->omp_clause.subcode.map_kind)
 #define OMP_CLAUSE_SET_MAP_KIND(NODE, MAP_KIND) \
--- gcc/omp-low.c.jj    2015-09-24 20:20:32.000000000 +0200
+++ gcc/omp-low.c       2015-09-25 18:17:13.331812912 +0200
@@ -565,7 +565,7 @@ extract_omp_for_data (gomp_for *for_stmt
                         ? integer_zero_node : integer_one_node;
     }
 
-  int cnt = fd->collapse + (fd->ordered > 0 ? fd->ordered - 1 : 0);
+  int cnt = fd->ordered ? fd->ordered : fd->collapse;
   for (i = 0; i < cnt; i++)
     {
       if (i == 0 && fd->collapse == 1 && (fd->ordered == 0 || loops == NULL))
@@ -6761,7 +6761,7 @@ expand_omp_for_init_counts (struct omp_f
       return;
     }
 
-  for (i = fd->collapse; i < fd->collapse + fd->ordered - 1; i++)
+  for (i = fd->collapse; i < fd->ordered; i++)
     {
       tree itype = TREE_TYPE (fd->loops[i].v);
       counts[i] = NULL_TREE;
@@ -6770,12 +6770,12 @@ expand_omp_for_init_counts (struct omp_f
                       fold_convert (itype, fd->loops[i].n2));
       if (t && integer_zerop (t))
        {
-         for (i = fd->collapse; i < fd->collapse + fd->ordered - 1; i++)
+         for (i = fd->collapse; i < fd->ordered; i++)
            counts[i] = build_int_cst (type, 0);
          break;
        }
     }
-  for (i = 0; i < fd->collapse + (fd->ordered ? fd->ordered - 1 : 0); i++)
+  for (i = 0; i < (fd->ordered ? fd->ordered : fd->collapse); i++)
     {
       tree itype = TREE_TYPE (fd->loops[i].v);
 
@@ -7074,8 +7074,7 @@ expand_omp_ordered_source (gimple_stmt_i
   enum built_in_function source_ix = BUILT_IN_GOMP_DOACROSS_POST;
   gimple g
     = gimple_build_call (builtin_decl_explicit (source_ix), 1,
-                        build_fold_addr_expr (counts[fd->collapse
-                                                     + fd->ordered - 1]));
+                        build_fold_addr_expr (counts[fd->ordered]));
   gimple_set_location (g, loc);
   gsi_insert_before (gsi, g, GSI_SAME_STMT);
 }
@@ -7091,13 +7090,38 @@ expand_omp_ordered_sink (gimple_stmt_ite
   tree t, off, coff = NULL_TREE, deps = OMP_CLAUSE_DECL (c), cond = NULL_TREE;
   int i;
   gimple_stmt_iterator gsi2 = *gsi;
+  bool warned_step = false;
 
+  for (i = 0; i < fd->ordered; i++)
+    {
+      off = TREE_PURPOSE (deps);
+      if (!integer_zerop (off))
+       {
+         gcc_assert (fd->loops[i].cond_code == LT_EXPR
+                     || fd->loops[i].cond_code == GT_EXPR);
+         bool forward = fd->loops[i].cond_code == LT_EXPR;
+         if (forward ^ OMP_CLAUSE_DEPEND_SINK_NEGATIVE (deps))
+           warning_at (loc, 0, "%<depend(sink)%> clause waiting for "
+                               "lexically later iteration");
+         break;
+       }
+      deps = TREE_CHAIN (deps);
+    }
+  /* If all offsets corresponding to the collapsed loops are zero,
+     this depend clause can be ignored.  FIXME: but there is still a
+     flush needed.  We need to emit one __sync_synchronize () for it
+     though (perhaps conditionally)?  Solve this together with the
+     conservative dependence folding optimization.
+  if (i >= fd->collapse)
+    return;  */
+
+  deps = OMP_CLAUSE_DECL (c);
   gsi_prev (&gsi2);
   edge e1 = split_block (gsi_bb (gsi2), gsi_stmt (gsi2));
   edge e2 = split_block_after_labels (e1->dest);
 
   *gsi = gsi_after_labels (e1->dest);
-  for (i = 0; i < fd->collapse + fd->ordered - 1; i++)
+  for (i = 0; i < fd->ordered; i++)
     {
       tree itype = TREE_TYPE (fd->loops[i].v);
       if (POINTER_TYPE_P (itype))
@@ -7114,51 +7138,34 @@ expand_omp_ordered_sink (gimple_stmt_ite
          tree a;
          tree co = fold_convert_loc (loc, itype, off);
          if (POINTER_TYPE_P (TREE_TYPE (fd->loops[i].v)))
-           a = fold_build2_loc (loc, POINTER_PLUS_EXPR,
-                                TREE_TYPE (fd->loops[i].v), fd->loops[i].v,
-                                co);
+           {
+             if (OMP_CLAUSE_DEPEND_SINK_NEGATIVE (deps))
+               co = fold_build1_loc (loc, NEGATE_EXPR, itype, co);
+             a = fold_build2_loc (loc, POINTER_PLUS_EXPR,
+                                  TREE_TYPE (fd->loops[i].v), fd->loops[i].v,
+                                  co);
+           }
+         else if (OMP_CLAUSE_DEPEND_SINK_NEGATIVE (deps))
+           a = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (fd->loops[i].v),
+                                fd->loops[i].v, co);
          else
            a = fold_build2_loc (loc, PLUS_EXPR, TREE_TYPE (fd->loops[i].v),
                                 fd->loops[i].v, co);
-         if (!TYPE_UNSIGNED (itype)
-             || POINTER_TYPE_P (TREE_TYPE (fd->loops[i].v)))
+         if (fd->loops[i].cond_code == LT_EXPR)
            {
-             if (fd->loops[i].cond_code == LT_EXPR)
-               {
-                 if (wi::neg_p (co))
-                   t = fold_build2_loc (loc, GE_EXPR, boolean_type_node, a,
-                                        fd->loops[i].n1);
-                 else
-                   t = fold_build2_loc (loc, LT_EXPR, boolean_type_node, a,
-                                        fd->loops[i].n2);
-               }
-             else if (wi::neg_p (co))
-               t = fold_build2_loc (loc, GT_EXPR, boolean_type_node, a,
-                                    fd->loops[i].n2);
-             else
-               t = fold_build2_loc (loc, LE_EXPR, boolean_type_node, a,
+             if (OMP_CLAUSE_DEPEND_SINK_NEGATIVE (deps))
+               t = fold_build2_loc (loc, GE_EXPR, boolean_type_node, a,
                                     fd->loops[i].n1);
+             else
+               t = fold_build2_loc (loc, LT_EXPR, boolean_type_node, a,
+                                    fd->loops[i].n2);
            }
-         else if (fd->loops[i].cond_code == LT_EXPR)
-           {
-             a = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (fd->loops[i].v),
-                                  a, fd->loops[i].n1);
-             t = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (fd->loops[i].v),
-                                  fd->loops[i].n2, fd->loops[i].n1);
-             t = fold_build2_loc (loc, LT_EXPR, boolean_type_node, a, t);
-           }
+         else if (OMP_CLAUSE_DEPEND_SINK_NEGATIVE (deps))
+           t = fold_build2_loc (loc, GT_EXPR, boolean_type_node, a,
+                                fd->loops[i].n2);
          else
-           {
-             a = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (fd->loops[i].v),
-                                  a, fd->loops[i].n2);
-             a = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (fd->loops[i].v),
-                                  a,
-                                  build_int_cst (TREE_TYPE (fd->loops[i].v),
-                                                 1));
-             t = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (fd->loops[i].v),
-                                  fd->loops[i].n1, fd->loops[i].n2);
-             t = fold_build2_loc (loc, LT_EXPR, boolean_type_node, a, t);
-           }
+           t = fold_build2_loc (loc, LE_EXPR, boolean_type_node, a,
+                                fd->loops[i].n1);
        }
       if (cond)
        cond = fold_build2_loc (loc, BIT_AND_EXPR, boolean_type_node, cond, t);
@@ -7172,15 +7179,19 @@ expand_omp_ordered_sink (gimple_stmt_ite
          : !integer_minus_onep (fd->loops[i].step))
        {
          if (TYPE_UNSIGNED (itype) && fd->loops[i].cond_code == GT_EXPR)
-           t = fold_build2_loc (loc, TRUNC_MOD_EXPR, itype,
-                                fold_build1_loc (loc, NEGATE_EXPR, itype,
-                                                 off),
+           t = fold_build2_loc (loc, TRUNC_MOD_EXPR, itype, off,
                                 fold_build1_loc (loc, NEGATE_EXPR, itype,
                                                  s));
          else
            t = fold_build2_loc (loc, TRUNC_MOD_EXPR, itype, off, s);
          t = fold_build2_loc (loc, EQ_EXPR, boolean_type_node, t,
                               build_int_cst (itype, 0));
+         if (integer_zerop (t) && !warned_step)
+           {
+             warning_at (loc, 0, "%<depend(sink)%> refers to iteration never "
+                                 "in the iteration space");
+             warned_step = true;
+           }
          cond = fold_build2_loc (loc, BIT_AND_EXPR, boolean_type_node,
                                  cond, t);
        }
@@ -7196,13 +7207,13 @@ expand_omp_ordered_sink (gimple_stmt_ite
          t = fold_convert_loc (loc, fd->iter_type, t);
        }
       if (TYPE_UNSIGNED (itype) && fd->loops[i].cond_code == GT_EXPR)
-       off = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype,
-                              fold_build1_loc (loc, NEGATE_EXPR, itype,
-                                               off),
+       off = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, off,
                               fold_build1_loc (loc, NEGATE_EXPR, itype,
                                                s));
       else
        off = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, off, s);
+      if (OMP_CLAUSE_DEPEND_SINK_NEGATIVE (deps))
+       off = fold_build1_loc (loc, NEGATE_EXPR, itype, off);
       off = fold_convert_loc (loc, fd->iter_type, off);
       if (i <= fd->collapse - 1 && fd->collapse > 1)
        {
@@ -7251,7 +7262,7 @@ expand_omp_ordered_source_sink (struct o
 {
   struct omp_region *inner;
   int i;
-  for (i = fd->collapse - 1; i < fd->collapse + fd->ordered - 1; i++)
+  for (i = fd->collapse - 1; i < fd->ordered; i++)
     if (i == fd->collapse - 1 && fd->collapse > 1)
       counts[i] = NULL_TREE;
     else if (i >= fd->collapse && !cont_bb)
@@ -7261,9 +7272,10 @@ expand_omp_ordered_source_sink (struct o
       counts[i] = NULL_TREE;
     else
       counts[i] = create_tmp_var (fd->iter_type, ".orditer");
-  tree atype = build_array_type_nelts (fd->iter_type, fd->ordered);
-  counts[fd->collapse + fd->ordered - 1] = create_tmp_var (atype, ".orditera");
-  TREE_ADDRESSABLE (counts[fd->collapse + fd->ordered - 1]) = 1;
+  tree atype
+    = build_array_type_nelts (fd->iter_type, fd->ordered - fd->collapse + 1);
+  counts[fd->ordered] = create_tmp_var (atype, ".orditera");
+  TREE_ADDRESSABLE (counts[fd->ordered]) = 1;
 
   for (inner = region->inner; inner; inner = inner->next)
     if (inner->type == GIMPLE_OMP_ORDERED)
@@ -7286,25 +7298,25 @@ expand_omp_ordered_source_sink (struct o
       }
 }
 
-/* Wrap the body into fd->ordered - 1 loops that aren't collapsed.  */
+/* Wrap the body into fd->ordered - fd->collapse loops that aren't
+   collapsed.  */
 
 static basic_block
 expand_omp_for_ordered_loops (struct omp_for_data *fd, tree *counts,
                              basic_block cont_bb, basic_block body_bb)
 {
-  if (fd->ordered <= 1)
+  if (fd->ordered == fd->collapse)
     return cont_bb;
 
   if (!cont_bb)
     {
       gimple_stmt_iterator gsi = gsi_after_labels (body_bb);
-      for (int i = fd->collapse; i < fd->collapse + fd->ordered - 1; i++)
+      for (int i = fd->collapse; i < fd->ordered; i++)
        {
          tree type = TREE_TYPE (fd->loops[i].v);
          tree n1 = fold_convert (type, fd->loops[i].n1);
          expand_omp_build_assign (&gsi, fd->loops[i].v, n1);
-         tree aref = build4 (ARRAY_REF, fd->iter_type,
-                             counts[fd->collapse + fd->ordered - 1],
+         tree aref = build4 (ARRAY_REF, fd->iter_type, counts[fd->ordered],
                              size_int (i - fd->collapse + 1),
                              NULL_TREE, NULL_TREE);
          expand_omp_build_assign (&gsi, aref, build_zero_cst (fd->iter_type));
@@ -7312,7 +7324,7 @@ expand_omp_for_ordered_loops (struct omp
       return NULL;
     }
 
-  for (int i = fd->collapse + fd->ordered - 2; i >= fd->collapse; i--)
+  for (int i = fd->ordered - 1; i >= fd->collapse; i--)
     {
       tree t, type = TREE_TYPE (fd->loops[i].v);
       gimple_stmt_iterator gsi = gsi_after_labels (body_bb);
@@ -7321,8 +7333,7 @@ expand_omp_for_ordered_loops (struct omp
       if (counts[i])
        expand_omp_build_assign (&gsi, counts[i],
                                 build_zero_cst (fd->iter_type));
-      tree aref = build4 (ARRAY_REF, fd->iter_type,
-                         counts[fd->collapse + fd->ordered - 1],
+      tree aref = build4 (ARRAY_REF, fd->iter_type, counts[fd->ordered],
                          size_int (i - fd->collapse + 1),
                          NULL_TREE, NULL_TREE);
       expand_omp_build_assign (&gsi, aref, build_zero_cst (fd->iter_type));
@@ -7358,8 +7369,7 @@ expand_omp_for_ordered_loops (struct omp
          t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
                                        true, GSI_SAME_STMT);
        }
-      aref = build4 (ARRAY_REF, fd->iter_type,
-                    counts[fd->collapse + fd->ordered - 1],
+      aref = build4 (ARRAY_REF, fd->iter_type, counts[fd->ordered],
                     size_int (i - fd->collapse + 1), NULL_TREE, NULL_TREE);
       expand_omp_build_assign (&gsi, aref, t);
       gsi_prev (&gsi);
@@ -7535,8 +7545,7 @@ expand_omp_for_generic (struct omp_regio
       int first_zero_iter1 = -1, first_zero_iter2 = -1;
       basic_block zero_iter1_bb = NULL, zero_iter2_bb = NULL, l2_dom_bb = NULL;
 
-      counts = XALLOCAVEC (tree, fd->collapse
-                                + (fd->ordered ? fd->ordered - 1 + 1 : 0));
+      counts = XALLOCAVEC (tree, fd->ordered ? fd->ordered + 1 : fd->collapse);
       expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
                                  zero_iter1_bb, first_zero_iter1,
                                  zero_iter2_bb, first_zero_iter2, l2_dom_bb);
@@ -7547,7 +7556,7 @@ expand_omp_for_generic (struct omp_regio
             some loop has zero iterations.  But the body shouldn't
             be executed in that case, so just avoid uninit warnings.  */
          for (i = first_zero_iter1;
-              i < fd->collapse + (fd->ordered ? fd->ordered - 1 : 0); i++)
+              i < (fd->ordered ? fd->ordered : fd->collapse); i++)
            if (SSA_VAR_P (counts[i]))
              TREE_NO_WARNING (counts[i]) = 1;
          gsi_prev (&gsi);
@@ -7564,7 +7573,7 @@ expand_omp_for_generic (struct omp_regio
          /* Some counts[i] vars might be uninitialized if
             some loop has zero iterations.  But the body shouldn't
             be executed in that case, so just avoid uninit warnings.  */
-         for (i = first_zero_iter2; i < fd->collapse + fd->ordered - 1; i++)
+         for (i = first_zero_iter2; i < fd->ordered; i++)
            if (SSA_VAR_P (counts[i]))
              TREE_NO_WARNING (counts[i]) = 1;
          if (zero_iter1_bb)
@@ -7640,18 +7649,20 @@ expand_omp_for_generic (struct omp_regio
       t3 = build_fold_addr_expr (istart0);
       if (fd->ordered)
        {
-         t0 = build_int_cst (unsigned_type_node, fd->ordered);
+         t0 = build_int_cst (unsigned_type_node,
+                             fd->ordered - fd->collapse + 1);
          arr = create_tmp_var (build_array_type_nelts (fd->iter_type,
-                                                       fd->ordered),
+                                                       fd->ordered
+                                                       - fd->collapse + 1),
                                ".omp_counts");
          DECL_NAMELESS (arr) = 1;
          TREE_ADDRESSABLE (arr) = 1;
          TREE_STATIC (arr) = 1;
          vec<constructor_elt, va_gc> *v;
-         vec_alloc (v, fd->ordered);
+         vec_alloc (v, fd->ordered - fd->collapse + 1);
          int idx;
 
-         for (idx = 0; idx < fd->ordered; idx++)
+         for (idx = 0; idx < fd->ordered - fd->collapse + 1; idx++)
            {
              tree c;
              if (idx == 0 && fd->collapse > 1)
@@ -7927,7 +7938,7 @@ expand_omp_for_generic (struct omp_regio
         those counts only for collapsed loops, and only for the 2nd
         till the last collapsed one.  Move those one element earlier,
         we'll use counts[fd->collapse - 1] for the first source/sink
-        iteration counter and so on and counts[fd->collapse + fd->ordered - 1]
+        iteration counter and so on and counts[fd->ordered]
         as the array holding the current counter values for
         depend(source).  */
       if (fd->collapse > 1)
@@ -7944,8 +7955,7 @@ expand_omp_for_generic (struct omp_regio
          t = fold_build2 (PLUS_EXPR, fd->iter_type, counts[fd->collapse - 1],
                           build_int_cst (fd->iter_type, 1));
          expand_omp_build_assign (&gsi, counts[fd->collapse - 1], t);
-         tree aref = build4 (ARRAY_REF, fd->iter_type,
-                             counts[fd->collapse + fd->ordered - 1],
+         tree aref = build4 (ARRAY_REF, fd->iter_type, counts[fd->ordered],
                              size_zero_node, NULL_TREE, NULL_TREE);
          expand_omp_build_assign (&gsi, aref, counts[fd->collapse - 1]);
          t = counts[fd->collapse - 1];
@@ -7959,8 +7969,7 @@ expand_omp_for_generic (struct omp_regio
          t = fold_convert (fd->iter_type, t);
        }
       gsi = gsi_last_bb (l0_bb);
-      tree aref = build4 (ARRAY_REF, fd->iter_type,
-                         counts[fd->collapse + fd->ordered - 1],
+      tree aref = build4 (ARRAY_REF, fd->iter_type, counts[fd->ordered],
                          size_zero_node, NULL_TREE, NULL_TREE);
       t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
                                    false, GSI_CONTINUE_LINKING);
@@ -8001,8 +8010,8 @@ expand_omp_for_generic (struct omp_regio
                  t = fold_convert (fd->iter_type, t);
                }
              tree aref = build4 (ARRAY_REF, fd->iter_type,
-                                 counts[fd->collapse + fd->ordered - 1],
-                                 size_zero_node, NULL_TREE, NULL_TREE);
+                                 counts[fd->ordered], size_zero_node,
+                                 NULL_TREE, NULL_TREE);
              t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
                                            true, GSI_SAME_STMT);
              expand_omp_build_assign (&gsi, aref, t);
@@ -8050,7 +8059,7 @@ expand_omp_for_generic (struct omp_regio
   gsi_insert_after (&gsi, call_stmt, GSI_SAME_STMT);
   if (fd->ordered)
     {
-      tree arr = counts[fd->collapse + fd->ordered - 1];
+      tree arr = counts[fd->ordered];
       tree clobber = build_constructor (TREE_TYPE (arr), NULL);
       TREE_THIS_VOLATILE (clobber) = 1;
       gsi_insert_after (&gsi, gimple_build_assign (arr, clobber),
@@ -13613,8 +13622,7 @@ lower_depend_clauses (tree *pclauses, gi
          break;
        case OMP_CLAUSE_DEPEND_SOURCE:
        case OMP_CLAUSE_DEPEND_SINK:
-         /* FIXME:  */
-         break;
+         /* FALLTHRU */
        default:
          gcc_unreachable ();
        }
--- gcc/tree-pretty-print.c.jj  2015-09-03 16:35:58.000000000 +0200
+++ gcc/tree-pretty-print.c     2015-09-25 15:04:46.911844111 +0200
@@ -569,7 +569,9 @@ dump_omp_clause (pretty_printer *pp, tre
                if (TREE_PURPOSE (t) != integer_zero_node)
                  {
                    tree p = TREE_PURPOSE (t);
-                   if (!wi::neg_p (p, TYPE_SIGN (TREE_TYPE (p))))
+                   if (OMP_CLAUSE_DEPEND_SINK_NEGATIVE (t))
+                     pp_minus (pp);
+                   else
                      pp_plus (pp);
                    dump_generic_node (pp, TREE_PURPOSE (t), spc, flags,
                                       false);
--- gcc/c/c-parser.c.jj 2015-09-10 10:45:20.000000000 +0200
+++ gcc/c/c-parser.c    2015-09-25 14:47:20.501151011 +0200
@@ -11913,14 +11913,13 @@ c_parser_omp_clause_depend_sink (c_parse
 
       c_parser_consume_token (parser);
 
-      bool neg;
+      bool neg = false;
       if (c_parser_next_token_is (parser, CPP_MINUS))
        neg = true;
-      else if (c_parser_next_token_is (parser, CPP_PLUS))
-       neg = false;
-      else
+      else if (!c_parser_next_token_is (parser, CPP_PLUS))
        {
          addend = integer_zero_node;
+         neg = false;
          goto add_to_vector;
        }
       c_parser_consume_token (parser);
@@ -11937,21 +11936,15 @@ c_parser_omp_clause_depend_sink (c_parse
          c_parser_error (parser, "expected integer");
          return list;
        }
-      if (neg)
-       {
-         bool overflow;
-         wide_int offset = wi::neg (addend, &overflow);
-         addend = wide_int_to_tree (TREE_TYPE (addend), offset);
-         if (overflow)
-           warning_at (c_parser_peek_token (parser)->location,
-                       OPT_Woverflow,
-                       "overflow in implicit constant conversion");
-       }
       c_parser_consume_token (parser);
 
     add_to_vector:
       if (t != error_mark_node)
-       vec = tree_cons (addend, t, vec);
+       {
+         vec = tree_cons (addend, t, vec);
+         if (neg)
+           OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1;
+       }
 
       if (c_parser_next_token_is_not (parser, CPP_COMMA))
        break;
@@ -13645,6 +13638,7 @@ c_parser_omp_for_loop (location_t loc, c
   tree decl, cond, incr, save_break, save_cont, body, init, stmt, cl;
   tree declv, condv, incrv, initv, ret = NULL_TREE;
   tree pre_body = NULL_TREE, this_pre_body;
+  tree ordered_cl = NULL_TREE;
   bool fail = false, open_brace_parsed = false;
   int i, collapse = 1, ordered = 0, count, nbraces = 0;
   location_t for_loc;
@@ -13655,10 +13649,22 @@ c_parser_omp_for_loop (location_t loc, c
       collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
     else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
             && OMP_CLAUSE_ORDERED_EXPR (cl))
-      ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
+      {
+       ordered_cl = cl;
+       ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
+      }
+
+  if (ordered && ordered < collapse)
+    {
+      error_at (OMP_CLAUSE_LOCATION (ordered_cl),
+               "%<ordered%> clause parameter is less than %<collapse%>");
+      OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
+       = build_int_cst (NULL_TREE, collapse);
+      ordered = collapse;
+    }
 
   gcc_assert (collapse >= 1 && ordered >= 0);
-  count = collapse + (ordered > 0 ? ordered - 1 : 0);
+  count = ordered ? ordered : collapse;
 
   declv = make_tree_vec (count);
   initv = make_tree_vec (count);
--- gcc/cp/parser.c.jj  2015-09-10 12:03:29.000000000 +0200
+++ gcc/cp/parser.c     2015-09-25 14:47:29.098025038 +0200
@@ -30464,12 +30464,10 @@ cp_parser_omp_clause_depend_sink (cp_par
                                         id_loc);
        }
 
-      bool neg;
+      bool neg = false;
       if (cp_lexer_next_token_is (parser->lexer, CPP_MINUS))
        neg = true;
-      else if (cp_lexer_next_token_is (parser->lexer, CPP_PLUS))
-       neg = false;
-      else
+      else if (!cp_lexer_next_token_is (parser->lexer, CPP_PLUS))
        {
          addend = integer_zero_node;
          goto add_to_vector;
@@ -30488,21 +30486,15 @@ cp_parser_omp_clause_depend_sink (cp_par
          cp_parser_error (parser, "expected integer");
          return list;
        }
-      if (neg)
-       {
-         bool overflow;
-         wide_int offset = wi::neg (addend, &overflow);
-         addend = wide_int_to_tree (TREE_TYPE (addend), offset);
-         if (overflow)
-           warning_at (cp_lexer_peek_token (parser->lexer)->location,
-                       OPT_Woverflow,
-                       "overflow in implicit constant conversion");
-       }
       cp_lexer_consume_token (parser->lexer);
 
     add_to_vector:
       if (t != error_mark_node)
-       vec = tree_cons (addend, t, vec);
+       {
+         vec = tree_cons (addend, t, vec);
+         if (neg)
+           OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1;
+       }
 
       if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
        break;
@@ -32212,7 +32204,7 @@ cp_parser_omp_for_loop (cp_parser *parse
 {
   tree init, cond, incr, body, decl, pre_body = NULL_TREE, ret;
   tree real_decl, initv, condv, incrv, declv;
-  tree this_pre_body, cl;
+  tree this_pre_body, cl, ordered_cl = NULL_TREE;
   location_t loc_first;
   bool collapse_err = false;
   int i, collapse = 1, ordered = 0, count, nbraces = 0;
@@ -32223,10 +32215,22 @@ cp_parser_omp_for_loop (cp_parser *parse
       collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
     else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
             && OMP_CLAUSE_ORDERED_EXPR (cl))
-      ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
+      {
+       ordered_cl = cl;
+       ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
+      }
+
+  if (ordered && ordered < collapse)
+    {
+      error_at (OMP_CLAUSE_LOCATION (ordered_cl),
+               "%<ordered%> clause parameter is less than %<collapse%>");
+      OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
+       = build_int_cst (NULL_TREE, collapse);
+      ordered = collapse;
+    }
 
   gcc_assert (collapse >= 1 && ordered >= 0);
-  count = collapse + (ordered > 0 ? ordered - 1 : 0);
+  count = ordered ? ordered : collapse;
 
   declv = make_tree_vec (count);
   initv = make_tree_vec (count);
--- gcc/cp/pt.c.jj      2015-09-10 10:45:41.000000000 +0200
+++ gcc/cp/pt.c 2015-09-25 14:53:22.986839372 +0200
@@ -14086,7 +14086,10 @@ tsubst_omp_clause_decl (tree decl, tree
          && TREE_VALUE (decl) == length
          && TREE_CHAIN (decl) == chain)
        return decl;
-      return tree_cons (low_bound, length, chain);
+      tree ret = tree_cons (low_bound, length, chain);
+      OMP_CLAUSE_DEPEND_SINK_NEGATIVE (ret)
+       = OMP_CLAUSE_DEPEND_SINK_NEGATIVE (decl);
+      return ret;
     }
   tree ret = tsubst_expr (decl, args, complain, in_decl,
                          /*integral_constant_expression_p=*/false);
--- gcc/testsuite/c-c++-common/gomp/sink-1.c.jj 2015-07-15 13:00:32.000000000 
+0200
+++ gcc/testsuite/c-c++-common/gomp/sink-1.c    2015-09-25 16:47:40.294063449 
+0200
@@ -68,7 +68,7 @@ void
 foo (int n, int m, int o)
 {
   int i, j, k;
-  #pragma omp for collapse(2) ordered(2)
+  #pragma omp for collapse(2) ordered(3)
   for (i = 0; i < m; i++)
     {
       for (j = 0; j < n; j++)
--- gcc/testsuite/gcc.dg/gomp/sink-fold-2.c.jj  2015-09-24 19:37:06.000000000 
+0200
+++ gcc/testsuite/gcc.dg/gomp/sink-fold-2.c     2015-09-25 18:14:38.626071155 
+0200
@@ -11,8 +11,8 @@ funk ()
   for (i=0; i < N; i += 3)
     for (j=0; j < N; ++j)
     {
-#pragma omp ordered depend(sink:i-8,j-1) /* { dg-warning "ignoring sink clause 
with offset that is not a multiple" "" { xfail *-*-* } } */
-#pragma omp ordered depend(sink:i+3,j-1) /* { dg-error "first offset must be 
in opposite direction" "" { xfail *-*-* } } */
+#pragma omp ordered depend(sink:i-8,j-1) /* { dg-warning "refers to iteration 
never in the iteration space" } */
+#pragma omp ordered depend(sink:i+3,j-1) /* { dg-warning "waiting for 
lexically later iteration" } */
         bar();
 #pragma omp ordered depend(source)
     }
--- libgomp/testsuite/libgomp.c/doacross-1.c.jj 2015-09-24 20:20:32.000000000 
+0200
+++ libgomp/testsuite/libgomp.c/doacross-1.c    2015-09-25 16:54:47.118834681 
+0200
@@ -79,7 +79,7 @@ main ()
 #define D(n) C(n##0) C(n##1) C(n##2) C(n##3)
     D(m)
 #undef A
-    #pragma omp for collapse (2) ordered(60) schedule(dynamic, 15)
+    #pragma omp for collapse (2) ordered(61) schedule(dynamic, 15)
     for (i = 0; i < N / 32; i++)
       for (j = 7; j > 1; j--)
        for (k = 6; k >= 0; k -= 2)
@@ -119,7 +119,7 @@ main ()
              c[i][j][k] = 3;
            }
 
-    #pragma omp for collapse(2) ordered(3) lastprivate (i, j, k)
+    #pragma omp for collapse(2) ordered(4) lastprivate (i, j, k)
     for (i = 0; i < d + 1; i++)
       for (j = d + 1; j >= 0; j--)
        for (k = 0; k < d; k++)
@@ -136,7 +136,7 @@ main ()
        abort ();
       i = 8; j = 9; k = 10;
     }
-    #pragma omp for collapse(2) ordered(3) lastprivate (i, j, k, m)
+    #pragma omp for collapse(2) ordered(4) lastprivate (i, j, k, m)
     for (i = 0; i < d + 1; i++)
       for (j = d + 1; j >= 0; j--)
        for (k = 0; k < d + 2; k++)
@@ -150,7 +150,7 @@ main ()
     #pragma omp single
     if (i != 1 || j != -1 || k != 2 || m != 0)
       abort ();
-    #pragma omp for collapse(2) ordered(3) nowait
+    #pragma omp for collapse(2) ordered(4) nowait
     for (i = 0; i < d + 1; i++)
       for (j = d; j > 0; j--)
        for (k = 0; k < d + 2; k++)

        Jakub

Reply via email to