Hi!

Another thing being voted into OpenMP 5.0 these days are clarifications for
iterators - step must be integral, and whether it is > 0 determines if it
iterates up or down, so one can use downward iterators even with unsigned
iterator type, either just use signed negative step constant, or some signed
negative expression.  Wrap-around, both signed and unsigned, of the iterator
is unspecified behavior, which simplifies things.

Tested on x86_64-linux, committed to gomp-5_0-branch.

2018-08-02  Jakub Jelinek  <ja...@redhat.com>

        * gimplify.c (gimplify_omp_depend): Load block from elt 5 instead
        of 4, in 4 expect to find original step expression, gimplify it and
        use it to determine if iterating upwards or downwards.  When iterating
        downwards with unsigned iterator type, negate both the difference and
        step before division.
gcc/c/
        * c-parser.c (c_parser_omp_iterators): Build vector with 6 elts
        instead of 5.
        (c_parser_omp_clause_depend): Put block into elt 5 instead of 4.
        * c-typeck.c (c_omp_finish_iterators): Remove iterator if step is
        errorneous, diagnose if step doesn't have integral type.  Remember
        original step expression wrapped with save_expr and store that to
        elt 4.
gcc/cp/
        * parser.c (cp_parser_omp_iterators): Build vector with 6 elts
        instead of 5.
        (cp_parser_omp_clause_depend): Put block into elt 5 instead of 4.
        * semantics.c (cp_omp_finish_iterators): Remove iterator if step is
        errorneous, diagnose if step doesn't have integral type.  Remember
        original step expression wrapped with save_expr and store that to
        elt 4.  If processing_template_decl, punt earlier if begin/end/step
        are type dependent expression, and only update step to the orig_step.
        * pt.c (tsubst_omp_clause_decl): Put block into elt 5 instead of 4.
gcc/testsuite/
        * c-c++-common/gomp/depend-iterator-2.c (f1): Adjust expected
        diagnostics, split the test with step 3.5 into one where only
        begin/end are floating point, and one where only step is floating
        point.
        * g++.dg/gomp/depend-iterator-2.C (f1, f3): Likewise.
libgomp/
        * testsuite/libgomp.c-c++-common/depend-iterator-1.c: Add tests for
        unsigned iterators, add gaps in between different arr2 bits.
        * testsuite/libgomp.c++/depend-iterator-1.C: Likewise.

--- gcc/gimplify.c.jj   2018-08-01 16:36:33.391000517 +0200
+++ gcc/gimplify.c      2018-08-02 17:59:48.980047042 +0200
@@ -7572,7 +7572,9 @@ gimplify_omp_depend (tree *list_p, gimpl
                                       is_gimple_val, fb_rvalue) == GS_ERROR
                        || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
                                          is_gimple_val, fb_rvalue) == GS_ERROR
-                       || (gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
+                       || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
+                                         is_gimple_val, fb_rvalue) == GS_ERROR
+                       || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
                                           is_gimple_val, fb_rvalue)
                            == GS_ERROR))
                      return 2;
@@ -7580,12 +7582,13 @@ gimplify_omp_depend (tree *list_p, gimpl
                    tree begin = TREE_VEC_ELT (it, 1);
                    tree end = TREE_VEC_ELT (it, 2);
                    tree step = TREE_VEC_ELT (it, 3);
+                   tree orig_step = TREE_VEC_ELT (it, 4);
                    tree type = TREE_TYPE (var);
                    tree stype = TREE_TYPE (step);
                    location_t loc = DECL_SOURCE_LOCATION (var);
                    tree endmbegin;
                    /* Compute count for this iterator as
-                      step > 0
+                      orig_step > 0
                       ? (begin < end ? (end - begin + (step - 1)) / step : 0)
                       : (begin > end ? (end - begin + (step + 1)) / step : 0)
                       and compute product of those for the entire depend
@@ -7608,8 +7611,14 @@ gimplify_omp_depend (tree *list_p, gimpl
                                           pos, step);
                    tree neg = fold_build2_loc (loc, PLUS_EXPR, stype,
                                                endmbegin, stepp1);
+                   if (TYPE_UNSIGNED (stype))
+                     {
+                       neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
+                       step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
+                     }
                    neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
                                           neg, step);
+                   step = NULL_TREE;
                    tree cond = fold_build2_loc (loc, LT_EXPR,
                                                 boolean_type_node,
                                                 begin, end);
@@ -7619,8 +7628,10 @@ gimplify_omp_depend (tree *list_p, gimpl
                                            end, begin);
                    neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
                                           build_int_cst (stype, 0));
+                   tree osteptype = TREE_TYPE (orig_step);
                    cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
-                                           step, build_int_cst (stype, 0));
+                                           orig_step,
+                                           build_int_cst (osteptype, 0));
                    tree cnt = fold_build3_loc (loc, COND_EXPR, stype,
                                                cond, pos, neg);
                    cnt = fold_convert_loc (loc, sizetype, cnt);
@@ -7779,7 +7790,7 @@ gimplify_omp_depend (tree *list_p, gimpl
              {
                if (last_bind)
                  gimplify_and_add (last_bind, pre_p);
-               tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 4);
+               tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
                last_bind = build3 (BIND_EXPR, void_type_node,
                                    BLOCK_VARS (block), NULL, block);
                TREE_SIDE_EFFECTS (last_bind) = 1;
@@ -7791,8 +7802,8 @@ gimplify_omp_depend (tree *list_p, gimpl
                    tree begin = TREE_VEC_ELT (it, 1);
                    tree end = TREE_VEC_ELT (it, 2);
                    tree step = TREE_VEC_ELT (it, 3);
+                   tree orig_step = TREE_VEC_ELT (it, 4);
                    tree type = TREE_TYPE (var);
-                   tree stype = TREE_TYPE (step);
                    location_t loc = DECL_SOURCE_LOCATION (var);
                    /* Emit:
                       var = begin;
@@ -7801,7 +7812,7 @@ gimplify_omp_depend (tree *list_p, gimpl
                       ...
                       var = var + step;
                       cond_label:
-                      if (step > 0) {
+                      if (orig_step > 0) {
                         if (var < end) goto beg_label;
                       } else {
                         if (var > end) goto beg_label;
@@ -7846,8 +7857,10 @@ gimplify_omp_depend (tree *list_p, gimpl
                      = fold_build3_loc (loc, COND_EXPR, void_type_node,
                                         cond, build_and_jump (&beg_label),
                                         void_node);
+                   tree osteptype = TREE_TYPE (orig_step);
                    cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
-                                           step, build_int_cst (stype, 0));
+                                           orig_step,
+                                           build_int_cst (osteptype, 0));
                    tem = fold_build3_loc (loc, COND_EXPR, void_type_node,
                                           cond, pos, neg);
                    append_to_statement_list_force (tem, p);
--- gcc/c/c-parser.c.jj 2018-08-01 17:27:10.069513226 +0200
+++ gcc/c/c-parser.c    2018-08-02 14:14:40.138818877 +0200
@@ -13911,7 +13911,7 @@ c_parser_omp_iterators (c_parser *parser
       DECL_CONTEXT (iter_var) = current_function_decl;
       pushdecl (iter_var);
 
-      *last = make_tree_vec (5);
+      *last = make_tree_vec (6);
       TREE_VEC_ELT (*last, 0) = iter_var;
       TREE_VEC_ELT (*last, 1) = begin;
       TREE_VEC_ELT (*last, 2) = end;
@@ -14031,7 +14031,7 @@ c_parser_omp_clause_depend (c_parser *pa
          if (iterators == error_mark_node)
            iterators = NULL_TREE;
          else
-           TREE_VEC_ELT (iterators, 4) = block;
+           TREE_VEC_ELT (iterators, 5) = block;
        }
 
       for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
--- gcc/c/c-typeck.c.jj 2018-08-01 17:00:46.329549760 +0200
+++ gcc/c/c-typeck.c    2018-08-02 18:57:31.969477582 +0200
@@ -13112,6 +13112,7 @@ c_omp_finish_iterators (tree iter)
       tree begin = TREE_VEC_ELT (it, 1);
       tree end = TREE_VEC_ELT (it, 2);
       tree step = TREE_VEC_ELT (it, 3);
+      tree orig_step;
       tree type = TREE_TYPE (var);
       location_t loc = DECL_SOURCE_LOCATION (var);
       if (type == error_mark_node)
@@ -13138,11 +13139,24 @@ c_omp_finish_iterators (tree iter)
          ret = true;
          continue;
        }
-
+      else if (step == error_mark_node
+              || TREE_TYPE (step) == error_mark_node)
+       {
+         ret = true;
+         continue;
+       }
+      else if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
+       {
+         error_at (EXPR_LOC_OR_LOC (step, loc),
+                   "iterator step with non-integral type");
+         ret = true;
+         continue;
+       }
       begin = c_fully_fold (build_c_cast (loc, type, begin), false, NULL);
       end = c_fully_fold (build_c_cast (loc, type, end), false, NULL);
+      orig_step = save_expr (c_fully_fold (step, false, NULL));
       tree stype = POINTER_TYPE_P (type) ? sizetype : type;
-      step = c_fully_fold (build_c_cast (loc, stype, step), false, NULL);
+      step = c_fully_fold (build_c_cast (loc, stype, orig_step), false, NULL);
       if (POINTER_TYPE_P (type))
        {
          begin = save_expr (begin);
@@ -13161,7 +13175,8 @@ c_omp_finish_iterators (tree iter)
 
       if (begin == error_mark_node
          || end == error_mark_node
-         || step == error_mark_node)
+         || step == error_mark_node
+         || orig_step == error_mark_node)
        {
          ret = true;
          continue;
@@ -13211,6 +13226,7 @@ c_omp_finish_iterators (tree iter)
       TREE_VEC_ELT (it, 1) = begin;
       TREE_VEC_ELT (it, 2) = end;
       TREE_VEC_ELT (it, 3) = step;
+      TREE_VEC_ELT (it, 4) = orig_step;
     }
   return ret;
 }
--- gcc/cp/parser.c.jj  2018-08-01 17:37:54.378605484 +0200
+++ gcc/cp/parser.c     2018-08-02 15:12:57.043831778 +0200
@@ -33733,7 +33733,7 @@ cp_parser_omp_iterators (cp_parser *pars
       DECL_CONTEXT (iter_var) = current_function_decl;
       pushdecl (iter_var);
 
-      *last = make_tree_vec (5);
+      *last = make_tree_vec (6);
       TREE_VEC_ELT (*last, 0) = iter_var;
       TREE_VEC_ELT (*last, 1) = begin;
       TREE_VEC_ELT (*last, 2) = end;
@@ -33867,7 +33867,7 @@ cp_parser_omp_clause_depend (cp_parser *
          if (iterators == error_mark_node)
            iterators = NULL_TREE;
          else
-           TREE_VEC_ELT (iterators, 4) = block;
+           TREE_VEC_ELT (iterators, 5) = block;
        }
 
       for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
--- gcc/cp/semantics.c.jj       2018-08-01 17:16:25.767685638 +0200
+++ gcc/cp/semantics.c  2018-08-02 18:57:07.374400371 +0200
@@ -5868,6 +5868,7 @@ cp_omp_finish_iterators (tree iter)
       tree begin = TREE_VEC_ELT (it, 1);
       tree end = TREE_VEC_ELT (it, 2);
       tree step = TREE_VEC_ELT (it, 3);
+      tree orig_step;
       tree type = TREE_TYPE (var);
       location_t loc = DECL_SOURCE_LOCATION (var);
       if (type == error_mark_node)
@@ -5890,12 +5891,31 @@ cp_omp_finish_iterators (tree iter)
          ret = true;
          continue;
        }
+      if (type_dependent_expression_p (begin)
+         || type_dependent_expression_p (end)
+         || type_dependent_expression_p (step))
+       continue;
+      else if (error_operand_p (step))
+       {
+         ret = true;
+         continue;
+       }
+      else if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
+       {
+         error_at (EXPR_LOC_OR_LOC (step, loc),
+                   "iterator step with non-integral type");
+         ret = true;
+         continue;
+       }
 
       begin = mark_rvalue_use (begin);
       end = mark_rvalue_use (end);
       step = mark_rvalue_use (step);
       begin = cp_build_c_cast (type, begin, tf_warning_or_error);
       end = cp_build_c_cast (type, end, tf_warning_or_error);
+      orig_step = step;
+      if (!processing_template_decl)
+       step = orig_step = save_expr (step);
       tree stype = POINTER_TYPE_P (type) ? sizetype : type;
       step = cp_build_c_cast (stype, step, tf_warning_or_error);
       if (POINTER_TYPE_P (type) && !processing_template_decl)
@@ -5912,6 +5932,7 @@ cp_omp_finish_iterators (tree iter)
          begin = maybe_constant_value (begin);
          end = maybe_constant_value (end);
          step = maybe_constant_value (step);
+         orig_step = maybe_constant_value (orig_step);
        }
       if (integer_zerop (step))
        {
@@ -5922,7 +5943,8 @@ cp_omp_finish_iterators (tree iter)
 
       if (begin == error_mark_node
          || end == error_mark_node
-         || step == error_mark_node)
+         || step == error_mark_node
+         || orig_step == error_mark_node)
        {
          ret = true;
          continue;
@@ -5933,6 +5955,8 @@ cp_omp_finish_iterators (tree iter)
          begin = fold_build_cleanup_point_expr (TREE_TYPE (begin), begin);
          end = fold_build_cleanup_point_expr (TREE_TYPE (end), end);
          step = fold_build_cleanup_point_expr (TREE_TYPE (step), step);
+         orig_step = fold_build_cleanup_point_expr (TREE_TYPE (orig_step),
+                                                    orig_step);
        }
       hash_set<tree> pset;
       tree it2;
@@ -5969,7 +5993,13 @@ cp_omp_finish_iterators (tree iter)
        }
       TREE_VEC_ELT (it, 1) = begin;
       TREE_VEC_ELT (it, 2) = end;
-      TREE_VEC_ELT (it, 3) = step;
+      if (processing_template_decl)
+       TREE_VEC_ELT (it, 3) = orig_step;
+      else
+       {
+         TREE_VEC_ELT (it, 3) = step;
+         TREE_VEC_ELT (it, 4) = orig_step;
+       }
     }
   return ret;
 }
--- gcc/cp/pt.c.jj      2018-08-01 17:39:48.853977209 +0200
+++ gcc/cp/pt.c 2018-08-02 16:05:50.445344053 +0200
@@ -15983,7 +15983,7 @@ tsubst_omp_clause_decl (tree decl, tree
              TREE_CHAIN (*tp) = NULL_TREE;
              tp = &TREE_CHAIN (*tp);
            }
-         TREE_VEC_ELT (ret, 4) = poplevel (1, 1, 0);
+         TREE_VEC_ELT (ret, 5) = poplevel (1, 1, 0);
          iterator_cache[0] = TREE_PURPOSE (decl);
          iterator_cache[1] = ret;
        }
--- gcc/testsuite/c-c++-common/gomp/depend-iterator-2.c.jj      2018-08-01 
18:47:11.000000000 +0200
+++ gcc/testsuite/c-c++-common/gomp/depend-iterator-2.c 2018-08-02 
19:26:13.142704860 +0200
@@ -52,10 +52,11 @@ f1 (void)
   ;                                                            /* { dg-error 
"invalid cast from type 'S' to type 'int'" "" { target c++ } .-1 } */
   #pragma omp task depend (iterator (i = 2:*d:2) , in : a)     /* { dg-error 
"aggregate value used where an integer was expected" "" { target c } } */
   ;                                                            /* { dg-error 
"invalid cast from type 'S' to type 'int'" "" { target c++ } .-1 } */
-  #pragma omp task depend (iterator (i = 2:4:*d) , in : a)     /* { dg-error 
"aggregate value used where an integer was expected" "" { target c } } */
-  ;                                                            /* { dg-error 
"invalid cast from type 'S' to type 'int'" "" { target c++ } .-1 } */
-                                                               /* { dg-error 
"iterator 'i' has zero step" "" { target c } .-2 } */
-  #pragma omp task depend (iterator (i = 1.25:2.5:3.5) , in : a)
+  #pragma omp task depend (iterator (i = 2:4:*d) , in : a)     /* { dg-error 
"iterator step with non-integral type" } */
+  ;
+  #pragma omp task depend (iterator (i = 1.25:2.5:3) , in : a)
+  ;
+  #pragma omp task depend (iterator (i = 1:2:3.5) , in : a)    /* { dg-error 
"iterator step with non-integral type" } */
   ;
   #pragma omp task depend (iterator (int *p = 23 : h) , in : a)
   ;
--- gcc/testsuite/g++.dg/gomp/depend-iterator-2.C.jj    2018-08-01 
18:47:23.250933990 +0200
+++ gcc/testsuite/g++.dg/gomp/depend-iterator-2.C       2018-08-02 
19:37:21.773080622 +0200
@@ -43,7 +43,9 @@ f1 ()
   ;
   #pragma omp task depend (iterator (i = 0:4, j = 2:8:i) , in : a)     // { 
dg-error "step expression refers to outer iterator 'i'" }
   ;
-  #pragma omp task depend (iterator (i = 1.25:2.5:3.5) , in : a)
+  #pragma omp task depend (iterator (i = 1.25:2.5:3) , in : a)
+  ;
+  #pragma omp task depend (iterator (i = 1:2:3.5) , in : a)            // { 
dg-error "iterator step with non-integral type" }
   ;
   #pragma omp task depend (iterator (W *p = 23 : h) , in : a)
   ;
@@ -81,9 +83,11 @@ f3 ()
   ;
   #pragma omp task depend (iterator (i = 2:*d:2) , in : a)     // { dg-error 
"invalid cast from type 'S' to type 'int'" }
   ;
-  #pragma omp task depend (iterator (i = 2:4:*d) , in : a)     // { dg-error 
"invalid cast from type 'S' to type 'int'" }
+  #pragma omp task depend (iterator (i = 2:4:*d) , in : a)     // { dg-error 
"iterator step with non-integral type" }
+  ;
+  #pragma omp task depend (iterator (i = 1.25:2.5:3) , in : a)
   ;
-  #pragma omp task depend (iterator (i = 1.25:2.5:3.5) , in : a)
+  #pragma omp task depend (iterator (i = 1:2:3.5) , in : a)    // { dg-error 
"iterator step with non-integral type" }
   ;
   #pragma omp task depend (iterator (W *p = 23 : h) , in : a)
   ;
--- libgomp/testsuite/libgomp.c-c++-common/depend-iterator-1.c.jj       
2018-08-01 18:03:26.037649407 +0200
+++ libgomp/testsuite/libgomp.c-c++-common/depend-iterator-1.c  2018-08-02 
18:25:16.409444294 +0200
@@ -24,26 +24,43 @@ foo (int x, int y, long z)
       if (y < 0 || y > 60 || (y & 3) || z < 0 || z >= 4)
        abort ();
       #pragma omp atomic
-      arr2[y + z] = arr2[y + z] + 2;
+      arr2[y + z] = arr2[y + z] + 4;
       return &arr[y + z];
     case 3:
       if (z < 0 || z > 60 || (z & 3) || y < 0 || y >= 4)
        abort ();
       #pragma omp atomic
-      arr2[y + z] = arr2[y + z] + 4;
+      arr2[y + z] = arr2[y + z] + 16;
       return &arr[y + z];
     case 4:
       if (y != 0 || z > 64 || z <= 0)
        abort ();
       #pragma omp atomic
-      arr2[z - 1] = arr2[z - 1] + 8;
+      arr2[z - 1] = arr2[z - 1] + 64;
       return &arr[z - 1];
+    case 5:
+      if ((y & 3) != 0 || y < 64 || y >= 96
+         || (z & 127) != 0 || z < 512 || z >= 1024)
+       abort ();
+      y = (y - 64) + (z - 512) / 128;
+      #pragma omp atomic
+      arr2[y] = arr2[y] + 256;
+      return &arr[y];
+    case 6:
+      if ((y & 3) != 0 || y <= 64 || y > 96
+         || (z & 127) != 1 || z <= 513 || z > 1025)
+       abort ();
+      y = (y - 68) + (z - 641) / 128;
+      #pragma omp atomic
+      arr2[y] = arr2[y] + 1024;
+      return &arr[y];
     default:
       abort ();
     }
 }
 
-volatile int beg, end, step;
+volatile int beg, end, step, step2;
+volatile unsigned int begu, endu;
 
 int
 main ()
@@ -52,6 +69,9 @@ main ()
   beg = 60;
   end = -4;
   step = -4;
+  step2 = 4;
+  begu = -64U;
+  endu = -32U;
   #pragma omp parallel
   #pragma omp master
   {
@@ -66,16 +86,30 @@ main ()
        abort ();
       else
        arr[i] = arr[i] + 1;
-    #pragma omp task depend (iterator (int *p=&arr3[64]:&arr3[0]:-1) , in : \
+    #pragma omp task depend (iterator (int *p=&arr3[64]:&arr3[0]:-1) , inout : 
\
                             foo (4, 0, p - &arr3[0])[0]) depend (in : beg)
     for (i = 0; i < 64; i++)
       if (arr[i] != i + 1)
        abort ();
       else
        arr[i] = arr[i] + 2;
+    #pragma omp task depend (iterator (unsigned n=begu:endu:step2, unsigned 
int o = 512: 1024U: (unsigned char) 128), inout : \
+                            foo (5, n + 128, o)[0]) 
+    for (i = 0; i < 64; i++)
+      if (arr[i] != i + 3)
+       abort ();
+      else
+       arr[i] = arr[i] + 4;
+    #pragma omp task depend (iterator (int unsigned p=endu:begu:step,unsigned 
q= 1025U:513U:(signed char) -128), in : \
+                            foo (6, p + 128, q)[0]) 
+    for (i = 0; i < 64; i++)
+      if (arr[i] != i + 7)
+       abort ();
+      else
+       arr[i] = arr[i] + 8;
   }
   for (m = 0; m < 64; m++)
-    if (arr[m] != m + 3 || arr2[m] != 15)
+    if (arr[m] != m + 15 || arr2[m] != (m < 32 ? 1365 : 85))
       abort ();
   return 0;
 }
--- libgomp/testsuite/libgomp.c++/depend-iterator-1.C.jj        2018-08-01 
18:05:47.080082763 +0200
+++ libgomp/testsuite/libgomp.c++/depend-iterator-1.C   2018-08-02 
18:38:14.372092577 +0200
@@ -21,26 +21,43 @@ foo (int x, int y, long z)
       if (y < 0 || y > 60 || (y & 3) || z < 0 || z >= 4)
        abort ();
       #pragma omp atomic
-      arr2[y + z] = arr2[y + z] + 2;
+      arr2[y + z] = arr2[y + z] + 4;
       return &arr[y + z];
     case 3:
       if (z < 0 || z > 60 || (z & 3) || y < 0 || y >= 4)
        abort ();
       #pragma omp atomic
-      arr2[y + z] = arr2[y + z] + 4;
+      arr2[y + z] = arr2[y + z] + 16;
       return &arr[y + z];
     case 4:
       if (y != 0 || z > 64 || z <= 0)
        abort ();
       #pragma omp atomic
-      arr2[z - 1] = arr2[z - 1] + 8;
+      arr2[z - 1] = arr2[z - 1] + 64;
       return &arr[z - 1];
+    case 5:
+      if ((y & 3) != 0 || y < 64 || y >= 96
+         || (z & 127) != 0 || z < 512 || z >= 1024)
+       abort ();
+      y = (y - 64) + (z - 512) / 128;
+      #pragma omp atomic
+      arr2[y] = arr2[y] + 256;
+      return &arr[y];
+    case 6:
+      if ((y & 3) != 0 || y <= 64 || y > 96
+         || (z & 127) != 1 || z <= 513 || z > 1025)
+       abort ();
+      y = (y - 68) + (z - 641) / 128;
+      #pragma omp atomic
+      arr2[y] = arr2[y] + 1024;
+      return &arr[y];
     default:
       abort ();
     }
 }
 
-volatile int beg, end, step;
+volatile int beg, end, step, step2;
+volatile unsigned int begu, endu;
 
 template <int N>
 void
@@ -60,19 +77,33 @@ bar ()
        abort ();
       else
        arr[i] = arr[i] + 1;
-    #pragma omp task depend (iterator (int *p=&arr3[64]:&arr3[0]:-1), in : \
+    #pragma omp task depend (iterator (int *p=&arr3[64]:&arr3[0]:-1), inout : \
                             foo (4, 0, p - &arr3[0])[0]) depend (in : beg)
     for (i = 0; i < 64; i++)
       if (arr[i] != i + 1)
        abort ();
       else
        arr[i] = arr[i] + 2;
+    #pragma omp task depend (iterator (unsigned n=begu:endu:step2, unsigned 
int o = 512: 1024U: (unsigned char) 128), inout : \
+                            foo (5, n + 128, o)[0]) 
+    for (i = 0; i < 64; i++)
+      if (arr[i] != i + 3)
+       abort ();
+      else
+       arr[i] = arr[i] + 4;
+    #pragma omp task depend (iterator (int unsigned p=endu:begu:step,unsigned 
q= 1025U:513U:(signed char) -128), in : \
+                            foo (6, p + 128, q)[0]) 
+    for (i = 0; i < 64; i++)
+      if (arr[i] != i + 7)
+       abort ();
+      else
+       arr[i] = arr[i] + 8;
   }
 }
 
-template <typename A, typename B, typename C>
+template <typename A, typename B, typename C, typename D, typename E, typename 
F>
 void
-baz (A beg, A end, A step)
+baz (A beg, A end, A step, D begu, D endu, A step2)
 {
   #pragma omp parallel
   #pragma omp master
@@ -95,6 +126,20 @@ baz (A beg, A end, A step)
        abort ();
       else
        arr[i] = arr[i] + 2;
+    #pragma omp task depend (iterator (D n=begu:endu:step2, D o = 512: 
1024U:(E) 128), inout : \
+                            foo (5, n + 128, o)[0]) 
+    for (i = 0; i < 64; i++)
+      if (arr[i] != i + 3)
+       abort ();
+      else
+       arr[i] = arr[i] + 4;
+    #pragma omp task depend (iterator (D p=endu:begu:step,D q= 1025U:513U:(F) 
-128), in : \
+                            foo (6, p + 128, q)[0]) 
+    for (i = 0; i < 64; i++)
+      if (arr[i] != i + 7)
+       abort ();
+      else
+       arr[i] = arr[i] + 8;
   }
 }
 
@@ -105,15 +150,18 @@ main ()
   beg = 60;
   end = -4;
   step = -4;
+  step2 = 4;
+  begu = -64U;
+  endu = -32U;
   bar<0> ();
   for (m = 0; m < 64; m++)
-    if (arr[m] != m + 3 || arr2[m] != 15)
+    if (arr[m] != m + 15 || arr2[m] != (m < 32 ? 1365 : 85))
       abort ();
     else
       arr[m] = arr2[m] = 0;
-  baz<int, long int, int *> (beg, end, step);
+  baz<int, long int, int *, unsigned int, unsigned char, signed char> (beg, 
end, step, begu, endu, step2);
   for (m = 0; m < 64; m++)
-    if (arr[m] != m + 3 || arr2[m] != 15)
+    if (arr[m] != m + 15 || arr2[m] != (m < 32 ? 1365 : 85))
       abort ();
   return 0;
 }

        Jakub

Reply via email to