backport: re PR middle-end/80809 (Multi-free error for variable size array used within OpenMP task)

Backported from mainline
	2017-05-22  Jakub Jelinek  <jakub@redhat.com>

	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: r248488
This commit is contained in:
Jakub Jelinek 2017-05-26 12:14:37 +02:00 committed by Jakub Jelinek
parent e8f1beb231
commit 9f67f1462d
5 changed files with 117 additions and 2 deletions

View File

@ -2,7 +2,13 @@
Backported from mainline
2017-05-22 Jakub Jelinek <jakub@redhat.com>
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.

View File

@ -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));

View File

@ -2,7 +2,11 @@
Backported from mainline
2017-05-22 Jakub Jelinek <jakub@redhat.com>
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.

View File

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

View File

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