Hi! We split OMP_TASKLOOP into 3 constructs, two GIMPLE_OMP_FOR with GIMPLE_OMP_PARALLEL sandwiched in between them, so that it is possible to compute number of iterations etc. before calling GOMP_taskloop*. Using the original iterator in the outer gfor doesn't play very well if the taskloop region is nested in other OpenMP regions like parallel. This patch just creates a temporary for that.
Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk so far, queued for 6.x. 2017-03-08 Jakub Jelinek <ja...@redhat.com> PR c/79940 * gimplify.c (gimplify_omp_for): Replace index var in outer taskloop statement with an artificial variable and add OMP_CLAUSE_PRIVATE clause for it. * testsuite/libgomp.c/pr79940.c: New test. --- gcc/gimplify.c.jj 2017-02-21 09:03:57.000000000 +0100 +++ gcc/gimplify.c 2017-03-08 10:06:11.926501447 +0100 @@ -10232,8 +10232,9 @@ gimplify_omp_for (tree *expr_p, gimple_s gimple_omp_for_set_combined_into_p (gfor, true); for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++) { - t = unshare_expr (gimple_omp_for_index (gfor, i)); - gimple_omp_for_set_index (gforo, i, t); + tree type = TREE_TYPE (gimple_omp_for_index (gfor, i)); + tree v = create_tmp_var (type); + gimple_omp_for_set_index (gforo, i, v); t = unshare_expr (gimple_omp_for_initial (gfor, i)); gimple_omp_for_set_initial (gforo, i, t); gimple_omp_for_set_cond (gforo, i, @@ -10241,7 +10242,13 @@ gimplify_omp_for (tree *expr_p, gimple_s t = unshare_expr (gimple_omp_for_final (gfor, i)); gimple_omp_for_set_final (gforo, i, t); t = unshare_expr (gimple_omp_for_incr (gfor, i)); + gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i)); + TREE_OPERAND (t, 0) = v; gimple_omp_for_set_incr (gforo, i, t); + t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE); + OMP_CLAUSE_DECL (t) = v; + OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo); + gimple_omp_for_set_clauses (gforo, t); } gimplify_seq_add_stmt (pre_p, gforo); } --- libgomp/testsuite/libgomp.c/pr79940.c.jj 2017-03-08 10:47:26.179154442 +0100 +++ libgomp/testsuite/libgomp.c/pr79940.c 2017-03-08 10:46:46.000000000 +0100 @@ -0,0 +1,47 @@ +/* PR c/79940 */ + +int +main () +{ + int i, j, l, m; + int a[10000], b[10000], c[10000]; + for (i = 0; i < 10000; i++) + { + a[i] = i; + b[i] = i & 31; + } +#pragma omp parallel shared(a, b, c) +#pragma omp single +#pragma omp taskloop shared(a, b, c) + for (i = 0; i < 10000; i++) + c[i] = a[i] + b[i]; +#pragma omp parallel +#pragma omp single + { + #pragma omp taskloop shared(a, b, c) lastprivate (i) + for (i = 0; i < 10000; i++) + c[i] += a[i] + b[i]; + l = i; + } +#pragma omp parallel +#pragma omp single +#pragma omp taskloop shared(a, b, c) collapse(2) + for (i = 0; i < 100; i++) + for (j = 0; j < 100; j++) + c[i * 100 + j] += a[i * 100 + j] + b[i * 100 + j]; +#pragma omp parallel +#pragma omp single + { + #pragma omp taskloop shared(a, b, c) lastprivate (i, j) + for (i = 0; i < 100; i++) + for (j = 0; j < 100; j++) + c[i * 100 + j] += a[i * 100 + j] + b[i * 100 + j]; + m = i * 100 + j; + } + for (i = 0; i < 10000; i++) + if (a[i] != i || b[i] != (i & 31) || c[i] != 4 * i + 4 * (i & 31)) + __builtin_abort (); + if (l != 10000 || m != 10100) + __builtin_abort (); + return 0; +} Jakub