re PR libgomp/69555 (libgomp.c++/target-6.C fails because of undefined behaviour)

PR libgomp/69555
	* gimplify.c (gimplify_decl_expr): For decls with REFERENCE_TYPE, also
	gimplify_type_sizes the type they refer to.
	(omp_notice_variable): Handle reference vars to VLAs.
	* omp-low.c (lower_omp_target): Emit setup of OMP_CLAUSE_PRIVATE reference
	to VLA decls in the second pass instead of first pass.

	* testsuite/libgomp.c++/pr69555-1.C: New test.
	* testsuite/libgomp.c++/pr69555-2.C: New test.

From-SVN: r233913
This commit is contained in:
Jakub Jelinek 2016-03-02 20:16:14 +01:00 committed by Jakub Jelinek
parent 268bc32008
commit da3d46cba8
6 changed files with 244 additions and 19 deletions

View File

@ -1,3 +1,12 @@
2016-03-02 Jakub Jelinek <jakub@redhat.com>
PR libgomp/69555
* gimplify.c (gimplify_decl_expr): For decls with REFERENCE_TYPE, also
gimplify_type_sizes the type they refer to.
(omp_notice_variable): Handle reference vars to VLAs.
* omp-low.c (lower_omp_target): Emit setup of OMP_CLAUSE_PRIVATE reference
to VLA decls in the second pass instead of first pass.
2016-03-02 Tom de Vries <tom@codesourcery.com>
PR tree-optimization/68659

View File

@ -1436,14 +1436,22 @@ gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
if ((TREE_CODE (decl) == TYPE_DECL
|| TREE_CODE (decl) == VAR_DECL)
&& !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
gimplify_type_sizes (TREE_TYPE (decl), seq_p);
{
gimplify_type_sizes (TREE_TYPE (decl), seq_p);
if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
}
/* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
in case its size expressions contain problematic nodes like CALL_EXPR. */
if (TREE_CODE (decl) == TYPE_DECL
&& DECL_ORIGINAL_TYPE (decl)
&& !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
{
gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
}
if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
{
@ -6264,16 +6272,30 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
&& (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
&& DECL_SIZE (decl)
&& TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
&& DECL_SIZE (decl))
{
splay_tree_node n2;
tree t = DECL_VALUE_EXPR (decl);
gcc_assert (TREE_CODE (t) == INDIRECT_REF);
t = TREE_OPERAND (t, 0);
gcc_assert (DECL_P (t));
n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
n2->value |= GOVD_SEEN;
if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
{
splay_tree_node n2;
tree t = DECL_VALUE_EXPR (decl);
gcc_assert (TREE_CODE (t) == INDIRECT_REF);
t = TREE_OPERAND (t, 0);
gcc_assert (DECL_P (t));
n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
n2->value |= GOVD_SEEN;
}
else if (lang_hooks.decls.omp_privatize_by_reference (decl)
&& TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
&& (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
!= INTEGER_CST))
{
splay_tree_node n2;
tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
gcc_assert (DECL_P (t));
n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
if (n2)
n2->value |= GOVD_SEEN;
}
}
shared = ((flags | n->value) & GOVD_SHARED) != 0;

View File

@ -16472,13 +16472,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
x = build_fold_addr_expr_loc (clause_loc, x);
}
else
{
tree atmp
= builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
tree rtype = TREE_TYPE (TREE_TYPE (new_var));
tree al = size_int (TYPE_ALIGN (rtype));
x = build_call_expr_loc (clause_loc, atmp, 2, x, al);
}
break;
x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
@ -16545,7 +16539,8 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
}
/* Handle GOMP_MAP_FIRSTPRIVATE_{POINTER,REFERENCE} in second pass,
so that firstprivate vars holding OMP_CLAUSE_SIZE if needed
are already handled. */
are already handled. Similarly OMP_CLAUSE_PRIVATE for VLAs
or references to VLAs. */
for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
switch (OMP_CLAUSE_CODE (c))
{
@ -16687,6 +16682,27 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
gimple_seq_add_stmt (&new_body,
gimple_build_assign (new_pvar, x));
}
else if (is_reference (var) && !is_gimple_omp_oacc (ctx->stmt))
{
location_t clause_loc = OMP_CLAUSE_LOCATION (c);
tree new_var = lookup_decl (var, ctx);
tree x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
if (TREE_CONSTANT (x))
break;
else
{
tree atmp
= builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
tree rtype = TREE_TYPE (TREE_TYPE (new_var));
tree al = size_int (TYPE_ALIGN (rtype));
x = build_call_expr_loc (clause_loc, atmp, 2, x, al);
}
x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
gimple_seq_add_stmt (&new_body,
gimple_build_assign (new_var, x));
}
break;
}

View File

@ -1,3 +1,9 @@
2016-03-02 Jakub Jelinek <jakub@redhat.com>
PR libgomp/69555
* testsuite/libgomp.c++/pr69555-1.C: New test.
* testsuite/libgomp.c++/pr69555-2.C: New test.
2016-02-26 Keith McDaniel <k.allen.mcdaniel@gmail.com>
Martin Jambor <mjambor@suse.cz>

View File

@ -0,0 +1,114 @@
// PR libgomp/69555
// { dg-do run }
#include <omp.h>
__attribute__((noinline, noclone)) void
f1 (int y)
{
int a[y - 2];
int (&c)[y - 2] = a;
c[0] = 111;
int e = 0;
#pragma omp parallel private (c) num_threads (4) reduction (+:e)
{
int v = omp_get_thread_num ();
for (int i = 0; i < y - 2; i++)
c[i] = i + v;
#pragma omp barrier
for (int i = 0; i < y - 2; i++)
if (c[i] != i + v)
e++;
}
if (c[0] != 111 || e)
__builtin_abort ();
}
__attribute__((noinline, noclone)) void
f2 (int y)
{
int a[y - 2];
int (&c)[y - 2] = a;
c[0] = 111;
#pragma omp task private (c)
{
int v = omp_get_thread_num ();
for (int i = 0; i < y - 2; i++)
c[i] = i + v;
asm volatile ("" : : "r" (&c[0]) : "memory");
for (int i = 0; i < y - 2; i++)
if (c[i] != i + v)
__builtin_abort ();
}
if (c[0] != 111)
__builtin_abort ();
}
__attribute__((noinline, noclone)) void
f3 (int y)
{
int a[y - 2];
int (&c)[y - 2] = a;
for (int i = 0; i < y - 2; i++)
c[i] = i + 4;
#pragma omp parallel firstprivate (c) num_threads (4)
{
int v = omp_get_thread_num ();
for (int i = 0; i < y - 2; i++)
{
if (c[i] != i + 4)
__builtin_abort ();
c[i] = i + v;
}
#pragma omp barrier
for (int i = 0; i < y - 2; i++)
if (c[i] != i + v)
__builtin_abort ();
}
for (int i = 0; i < y - 2; i++)
if (c[i] != i + 4)
__builtin_abort ();
}
__attribute__((noinline, noclone)) void
f4 (int y)
{
int a[y - 2];
int (&c)[y - 2] = a;
for (int i = 0; i < y - 2; i++)
c[i] = i + 4;
#pragma omp task firstprivate (c)
{
int v = omp_get_thread_num ();
for (int i = 0; i < y - 2; i++)
{
if (c[i] != i + 4)
__builtin_abort ();
c[i] = i + v;
}
asm volatile ("" : : "r" (&c[0]) : "memory");
for (int i = 0; i < y - 2; i++)
if (c[i] != i + v)
__builtin_abort ();
}
for (int i = 0; i < y - 2; i++)
if (c[i] != i + 4)
__builtin_abort ();
}
int
main ()
{
f1 (6);
f3 (6);
#pragma omp parallel num_threads (4)
{
f2 (6);
f4 (6);
}
return 0;
}

View File

@ -0,0 +1,58 @@
// PR libgomp/69555
// { dg-do run }
__attribute__((noinline, noclone)) void
f1 (int y)
{
int a[y - 2];
int (&c)[y - 2] = a;
for (int i = 0; i < y - 2; i++)
c[i] = i + 4;
#pragma omp target firstprivate (c)
{
for (int i = 0; i < y - 2; i++)
{
if (c[i] != i + 4)
__builtin_abort ();
c[i] = i + 9;
}
asm volatile ("" : : "r" (&c[0]) : "memory");
for (int i = 0; i < y - 2; i++)
if (c[i] != i + 9)
__builtin_abort ();
}
for (int i = 0; i < y - 2; i++)
if (c[i] != i + 4)
__builtin_abort ();
}
__attribute__((noinline, noclone)) void
f2 (int y)
{
int a[y - 2];
int (&c)[y - 2] = a;
for (int i = 0; i < y - 2; i++)
c[i] = i + 4;
#pragma omp target private (c)
{
for (int i = 0; i < y - 2; i++)
c[i] = i + 9;
asm volatile ("" : : "r" (&c[0]) : "memory");
for (int i = 0; i < y - 2; i++)
if (c[i] != i + 9)
__builtin_abort ();
}
for (int i = 0; i < y - 2; i++)
if (c[i] != i + 4)
__builtin_abort ();
}
int
main ()
{
f1 (6);
f2 (6);
return 0;
}