From: Jakub Jelinek Date: Mon, 8 Oct 2018 15:40:13 +0000 (+0200) Subject: omp-low.c (lower_omp_task_reductions): For array section reductions... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=df4e2adbfee63820fcf230dc6c1bd289cdd50178;p=thirdparty%2Fgcc.git omp-low.c (lower_omp_task_reductions): For array section reductions... * omp-low.c (lower_omp_task_reductions): For array section reductions, read address from avar array instead of computing it again at the end of taskgroup, as the base might have changed during the taskgroup. * testsuite/libgomp.c-c++-common/task-reduction-5.c: New test. From-SVN: r264938 --- diff --git a/gcc/ChangeLog.gomp b/gcc/ChangeLog.gomp index 41dcbcfcef90..854da5e4647d 100644 --- a/gcc/ChangeLog.gomp +++ b/gcc/ChangeLog.gomp @@ -1,3 +1,9 @@ +2018-10-08 Jakub Jelinek + + * omp-low.c (lower_omp_task_reductions): For array section reductions, + read address from avar array instead of computing it again at the end + of taskgroup, as the base might have changed during the taskgroup. + 2018-09-27 Jakub Jelinek * omp-low.c (lower_rec_input_clauses): Fix handling of diff --git a/gcc/omp-low.c b/gcc/omp-low.c index adb65c841b3f..8acffdb9bc29 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -6787,7 +6787,7 @@ lower_omp_task_reductions (omp_context *ctx, enum tree_code code, tree clauses, omp_task_reduction_iterate (pass, code, ccode, &c, &decl, &type, &next); c = next) { - tree var = decl, ref, orig_var = decl; + tree var = decl, ref; if (TREE_CODE (decl) == MEM_REF) { var = TREE_OPERAND (var, 0); @@ -6798,7 +6798,6 @@ lower_omp_task_reductions (omp_context *ctx, enum tree_code code, tree clauses, var = TREE_OPERAND (var, 0); else if (TREE_CODE (var) == INDIRECT_REF) var = TREE_OPERAND (var, 0); - orig_var = var; if (is_variable_sized (var)) { gcc_assert (DECL_HAS_VALUE_EXPR_P (var)); @@ -6895,48 +6894,17 @@ lower_omp_task_reductions (omp_context *ctx, enum tree_code code, tree clauses, rcode = PLUS_EXPR; if (TREE_CODE (decl) == MEM_REF) { - tree d = decl; tree type = TREE_TYPE (new_var); tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type)); tree i = create_tmp_var (TREE_TYPE (v), NULL); tree ptype = build_pointer_type (TREE_TYPE (type)); - tree bias = TREE_OPERAND (d, 1); - d = TREE_OPERAND (d, 0); - if (TREE_CODE (d) == POINTER_PLUS_EXPR) - { - tree b = TREE_OPERAND (d, 1); - b = maybe_lookup_decl_in_outer_ctx (b, ctx); - if (integer_zerop (bias)) - bias = b; - else - { - bias = fold_convert (TREE_TYPE (b), bias); - bias = fold_build2 (PLUS_EXPR, TREE_TYPE (b), b, bias); - } - d = TREE_OPERAND (d, 0); - } - /* For ref build_outer_var_ref already performs this, so - only new_var needs a dereference. */ - if (TREE_CODE (d) == INDIRECT_REF) - ref = build_fold_indirect_ref (ref); - else if (TREE_CODE (d) == ADDR_EXPR) - { - if (orig_var == var) - ref = build_fold_addr_expr (ref); - } - else - gcc_assert (orig_var == var); if (DECL_P (v)) { v = maybe_lookup_decl_in_outer_ctx (v, ctx); gimplify_expr (&v, end, NULL, is_gimple_val, fb_rvalue); } - if (!integer_zerop (bias)) - { - bias = fold_convert (sizetype, bias); - ref = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (ref), - ref, bias); - } + ref = build4 (ARRAY_REF, pointer_sized_int_node, avar, + size_int (7 + cnt * 3), NULL_TREE, NULL_TREE); new_var = build_fold_addr_expr (new_var); new_var = fold_convert (ptype, new_var); ref = fold_convert (ptype, ref); diff --git a/libgomp/ChangeLog.gomp b/libgomp/ChangeLog.gomp index cadbcb05c247..6e8b30c779d9 100644 --- a/libgomp/ChangeLog.gomp +++ b/libgomp/ChangeLog.gomp @@ -1,5 +1,7 @@ 2018-10-08 Jakub Jelinek + * testsuite/libgomp.c-c++-common/task-reduction-5.c: New test. + * env.c (gomp_affinity_format_var): Use %i instead of %T and %A instead of %a. * affinity-fmt.c (affinity_types): Change short forms h to H, diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-reduction-5.c b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-5.c new file mode 100644 index 000000000000..52880ec6f369 --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-5.c @@ -0,0 +1,55 @@ +extern +#ifdef __cplusplus +"C" +#endif +void abort (void); + +int *q; + +void +bar (int *p, int *r, int s) +{ + #pragma omp task in_reduction (*: p[0], q[0], r[s - 1]) + { + *p *= 4; + *q *= 5; + r[s - 1] *= 6; + } +} + +void +foo (int *p, int *r, int s) +{ + int *p2 = p; + #pragma omp taskgroup task_reduction (*: p[0], q[0], r[s]) + { + p = (int *) 0; + s++; + bar (p2, r, s); + r++; + #pragma omp taskwait + #pragma omp task in_reduction (*: p2[0], q[0], r[s - 2]) + { + *p2 *= 2; + *q *= 3; + r[s - 2] *= 7; + } + s++; + p2 = (int *) 0; + q = (int *) 0; + r = (int *) 0; + } +} + +int +main () +{ + int a = 1, b = 1, c[2] = { 1, 0 }; + q = &b; + #pragma omp parallel num_threads (2) + #pragma omp master + foo (&a, &c[0], 0); + if (a != 8 || b != 15 || c[0] != 42 || c[1] != 0) + abort (); + return 0; +}