[gomp5] Iterator fixes

Message ID 20180802182822.GH17988@tucnak
State New
Headers show
Series
  • [gomp5] Iterator fixes
Related show

Commit Message

Jakub Jelinek Aug. 2, 2018, 6:28 p.m.
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  <jakub@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.


	Jakub

Comments

Marek Polacek Aug. 2, 2018, 6:35 p.m. | #1
On Thu, Aug 02, 2018 at 08:28:22PM +0200, Jakub Jelinek wrote:
> --- 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)

You can use error_operand_p for this.

Marek

Patch

--- 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;
 }