From: Jakub Jelinek Date: Mon, 22 May 2017 18:54:54 +0000 (+0200) Subject: re PR middle-end/80809 (Multi-free error for variable size array used within OpenMP... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=655e52652b2af93ae6508dfc2026c6903bf391de;p=gcc.git re PR middle-end/80809 (Multi-free error for variable size array used within OpenMP task) PR middle-end/80809 * omp-low.c (finish_taskreg_remap): New function. (finish_taskreg_scan): If unit size of ctx->record_type is non-constant, unshare the size expression and replace decls in it with possible outer var refs. * testsuite/libgomp.c/pr80809-2.c: New test. * testsuite/libgomp.c/pr80809-3.c: New test. From-SVN: r248346 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cfa15c2a7e1..7bdd6f2c7a7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2017-05-22 Jakub Jelinek + PR middle-end/80809 + * omp-low.c (finish_taskreg_remap): New function. + (finish_taskreg_scan): If unit size of ctx->record_type + is non-constant, unshare the size expression and replace + decls in it with possible outer var refs. + PR middle-end/80809 * gimplify.c (omp_add_variable): For GOVD_DEBUG_PRIVATE use GOVD_SHARED rather than GOVD_PRIVATE with it. diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 26e6586a070..968075c3df5 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -1913,6 +1913,29 @@ scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx) } } +/* Helper function for finish_taskreg_scan, called through walk_tree. + If maybe_lookup_decl_in_outer_context returns non-NULL for some + tree, replace it in the expression. */ + +static tree +finish_taskreg_remap (tree *tp, int *walk_subtrees, void *data) +{ + if (VAR_P (*tp)) + { + omp_context *ctx = (omp_context *) data; + tree t = maybe_lookup_decl_in_outer_ctx (*tp, ctx); + if (t != *tp) + { + if (DECL_HAS_VALUE_EXPR_P (t)) + t = unshare_expr (DECL_VALUE_EXPR (t)); + *tp = t; + } + *walk_subtrees = 0; + } + else if (IS_TYPE_OR_DECL_P (*tp)) + *walk_subtrees = 0; + return NULL_TREE; +} /* If any decls have been made addressable during scan_omp, adjust their fields if needed, and layout record types @@ -2033,6 +2056,11 @@ finish_taskreg_scan (omp_context *ctx) layout_type (ctx->srecord_type); tree t = fold_convert_loc (loc, long_integer_type_node, TYPE_SIZE_UNIT (ctx->record_type)); + if (TREE_CODE (t) != INTEGER_CST) + { + t = unshare_expr (t); + walk_tree (&t, finish_taskreg_remap, ctx, NULL); + } gimple_omp_task_set_arg_size (ctx->stmt, t); t = build_int_cst (long_integer_type_node, TYPE_ALIGN_UNIT (ctx->record_type)); diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index c73683efff4..8209f9fa75c 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,5 +1,9 @@ 2017-05-22 Jakub Jelinek + PR middle-end/80809 + * testsuite/libgomp.c/pr80809-2.c: New test. + * testsuite/libgomp.c/pr80809-3.c: New test. + PR middle-end/80809 * testsuite/libgomp.c/pr80809-1.c: New test. diff --git a/libgomp/testsuite/libgomp.c/pr80809-2.c b/libgomp/testsuite/libgomp.c/pr80809-2.c new file mode 100644 index 00000000000..48af3707794 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr80809-2.c @@ -0,0 +1,35 @@ +/* PR middle-end/80809 */ +/* { dg-do run } */ + +__attribute__((noinline, noclone)) void +foo (int x) +{ + int i, v[x], w[16]; + for (i = 0; i < x; i++) + v[i] = i; + for (i = 0; i < 16; i++) + w[i] = 0; +#pragma omp parallel +#pragma omp single + for (i = 0; i < 16; i++) +#pragma omp task firstprivate (v) + { + int j; + for (j = 0; j < x; j++) + v[j] += i; + for (j = 0; j < x; j++) + w[i] += v[j]; + } + for (i = 0; i < 16; i++) + if (w[i] != (x - 1) * x / 2 + x * i) + __builtin_abort (); +} + +int +main () +{ + foo (4); + foo (27); + foo (196); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr80809-3.c b/libgomp/testsuite/libgomp.c/pr80809-3.c new file mode 100644 index 00000000000..7e0d17983e4 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr80809-3.c @@ -0,0 +1,42 @@ +/* PR middle-end/80809 */ +/* { dg-do run } */ + +__attribute__((noinline, noclone)) void +foo (int x) +{ + int i, v[x], w[16]; + for (i = 0; i < x; i++) + v[i] = i; + for (i = 0; i < 16; i++) + w[i] = 0; +#pragma omp parallel +#pragma omp single + { + int z[x]; + for (i = 0; i < x; i++) + z[0] = 0; + for (i = 0; i < 16; i++) +#pragma omp task firstprivate (z) firstprivate (v) + { + int j; + for (j = 0; j < x; j++) + z[j] = i; + for (j = 0; j < x; j++) + v[j] += z[j]; + for (j = 0; j < x; j++) + w[i] += v[j]; + } + } + for (i = 0; i < 16; i++) + if (w[i] != (x - 1) * x / 2 + x * i) + __builtin_abort (); +} + +int +main () +{ + foo (4); + foo (27); + foo (196); + return 0; +}