omp-low.c (lower_rec_input_clauses): Force max_vf if is_simd and on privatization clauses OMP_CLAUSE_DECL is...

* omp-low.c (lower_rec_input_clauses): Force max_vf if is_simd and
	on privatization clauses OMP_CLAUSE_DECL is privatized by reference
	and references a VLA.  Handle references to non-VLAs if is_simd
	all privatization clauses like reductions.
	(lower_rec_input_clauses) <case do_private, case do_firstprivate>:
	If omp_is_reference, use always omp simd arrays and set
	DECL_VALUE_EXPR in that case, if lower_rec_simd_input_clauses
	fails, emit reference initialization.

	* g++.dg/vect/simd-1.cc: New test.

From-SVN: r271947
This commit is contained in:
Jakub Jelinek 2019-06-05 09:36:30 +02:00 committed by Jakub Jelinek
parent 5259a047c3
commit 9ea2bfca6a
4 changed files with 224 additions and 4 deletions

View File

@ -1,3 +1,14 @@
2019-06-05 Jakub Jelinek <jakub@redhat.com>
* omp-low.c (lower_rec_input_clauses): Force max_vf if is_simd and
on privatization clauses OMP_CLAUSE_DECL is privatized by reference
and references a VLA. Handle references to non-VLAs if is_simd
all privatization clauses like reductions.
(lower_rec_input_clauses) <case do_private, case do_firstprivate>:
If omp_is_reference, use always omp simd arrays and set
DECL_VALUE_EXPR in that case, if lower_rec_simd_input_clauses
fails, emit reference initialization.
2019-06-05 Hongtao Liu <hongtao.liu@intel.com>
PR target/89803

View File

@ -3831,12 +3831,24 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
case OMP_CLAUSE_LASTPRIVATE:
if (is_variable_sized (OMP_CLAUSE_DECL (c)))
sctx.max_vf = 1;
else if (omp_is_reference (OMP_CLAUSE_DECL (c)))
{
tree rtype = TREE_TYPE (TREE_TYPE (OMP_CLAUSE_DECL (c)));
if (!TREE_CONSTANT (TYPE_SIZE_UNIT (rtype)))
sctx.max_vf = 1;
}
break;
case OMP_CLAUSE_REDUCTION:
case OMP_CLAUSE_IN_REDUCTION:
if (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
|| is_variable_sized (OMP_CLAUSE_DECL (c)))
sctx.max_vf = 1;
else if (omp_is_reference (OMP_CLAUSE_DECL (c)))
{
tree rtype = TREE_TYPE (TREE_TYPE (OMP_CLAUSE_DECL (c)));
if (!TREE_CONSTANT (TYPE_SIZE_UNIT (rtype)))
sctx.max_vf = 1;
}
break;
case OMP_CLAUSE_IF:
if (integer_zerop (OMP_CLAUSE_IF_EXPR (c)))
@ -4665,8 +4677,8 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
/* For reduction in SIMD loop, defer adding the
initialization of the reference, because if we decide
to use SIMD array for it, the initilization could cause
expansion ICE. */
if (c_kind == OMP_CLAUSE_REDUCTION && is_simd)
expansion ICE. Ditto for other privatization clauses. */
if (is_simd)
x = NULL_TREE;
else
{
@ -4777,10 +4789,21 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
tree y = lang_hooks.decls.omp_clause_dtor (c, new_var);
if ((TREE_ADDRESSABLE (new_var) || nx || y
|| OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
|| OMP_CLAUSE_CODE (c) == OMP_CLAUSE__CONDTEMP_)
|| OMP_CLAUSE_CODE (c) == OMP_CLAUSE__CONDTEMP_
|| omp_is_reference (var))
&& lower_rec_simd_input_clauses (new_var, ctx, &sctx,
ivar, lvar))
{
if (omp_is_reference (var))
{
gcc_assert (TREE_CODE (new_var) == MEM_REF);
tree new_vard = TREE_OPERAND (new_var, 0);
gcc_assert (DECL_P (new_vard));
SET_DECL_VALUE_EXPR (new_vard,
build_fold_addr_expr (lvar));
DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
}
if (nx)
x = lang_hooks.decls.omp_clause_default_ctor
(c, unshare_expr (ivar), x);
@ -4838,6 +4861,24 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
}
break;
}
if (omp_is_reference (var))
{
gcc_assert (TREE_CODE (new_var) == MEM_REF);
tree new_vard = TREE_OPERAND (new_var, 0);
gcc_assert (DECL_P (new_vard));
tree type = TREE_TYPE (TREE_TYPE (new_vard));
x = TYPE_SIZE_UNIT (type);
if (TREE_CONSTANT (x))
{
x = create_tmp_var_raw (type, get_name (var));
gimple_add_tmp_var (x);
TREE_ADDRESSABLE (x) = 1;
x = build_fold_addr_expr_loc (clause_loc, x);
x = fold_convert_loc (clause_loc,
TREE_TYPE (new_vard), x);
gimplify_assign (new_vard, x, ilist);
}
}
}
if (nx)
gimplify_and_add (nx, ilist);
@ -4925,6 +4966,28 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
if (OMP_CLAUSE_LINEAR_ARRAY (c))
{
if (omp_is_reference (var))
{
gcc_assert (TREE_CODE (new_var) == MEM_REF);
tree new_vard = TREE_OPERAND (new_var, 0);
gcc_assert (DECL_P (new_vard));
tree type = TREE_TYPE (TREE_TYPE (new_vard));
nx = TYPE_SIZE_UNIT (type);
if (TREE_CONSTANT (nx))
{
nx = create_tmp_var_raw (type,
get_name (var));
gimple_add_tmp_var (nx);
TREE_ADDRESSABLE (nx) = 1;
nx = build_fold_addr_expr_loc (clause_loc,
nx);
nx = fold_convert_loc (clause_loc,
TREE_TYPE (new_vard),
nx);
gimplify_assign (new_vard, nx, ilist);
}
}
x = lang_hooks.decls.omp_clause_linear_ctor
(c, new_var, x, t);
gimplify_and_add (x, ilist);
@ -4939,10 +5002,20 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
}
if ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LINEAR
|| TREE_ADDRESSABLE (new_var))
|| TREE_ADDRESSABLE (new_var)
|| omp_is_reference (var))
&& lower_rec_simd_input_clauses (new_var, ctx, &sctx,
ivar, lvar))
{
if (omp_is_reference (var))
{
gcc_assert (TREE_CODE (new_var) == MEM_REF);
tree new_vard = TREE_OPERAND (new_var, 0);
gcc_assert (DECL_P (new_vard));
SET_DECL_VALUE_EXPR (new_vard,
build_fold_addr_expr (lvar));
DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
}
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR)
{
tree iv = create_tmp_var (TREE_TYPE (new_var));
@ -4977,6 +5050,24 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
}
break;
}
if (omp_is_reference (var))
{
gcc_assert (TREE_CODE (new_var) == MEM_REF);
tree new_vard = TREE_OPERAND (new_var, 0);
gcc_assert (DECL_P (new_vard));
tree type = TREE_TYPE (TREE_TYPE (new_vard));
nx = TYPE_SIZE_UNIT (type);
if (TREE_CONSTANT (nx))
{
nx = create_tmp_var_raw (type, get_name (var));
gimple_add_tmp_var (nx);
TREE_ADDRESSABLE (nx) = 1;
nx = build_fold_addr_expr_loc (clause_loc, nx);
nx = fold_convert_loc (clause_loc,
TREE_TYPE (new_vard), nx);
gimplify_assign (new_vard, nx, ilist);
}
}
}
x = lang_hooks.decls.omp_clause_copy_ctor
(c, unshare_expr (new_var), x);

View File

@ -1,3 +1,7 @@
2019-06-05 Jakub Jelinek <jakub@redhat.com>
* g++.dg/vect/simd-1.cc: New test.
2019-06-05 Hongtao Liu <hongtao.liu@intel.com>
PR target/89803

View File

@ -0,0 +1,114 @@
// { dg-require-effective-target vect_simd_clones }
// { dg-additional-options "-fopenmp-simd" }
// { dg-additional-options "-mavx" { target avx_runtime } }
#include "../../gcc.dg/vect/tree-vect.h"
int w;
struct S {
int s, &t;
int *p;
S (int *x) : s (0), t (w), p (x) {};
void foo (short &, int &);
void bar (short &, int &);
void baz (short &, int &);
void qux (short &, int &);
};
__attribute__((noipa)) void
S::foo (short &x, int &y)
{
int *q = this->p;
#pragma omp simd lastprivate (x, s, t) private (y)
for (int i = 0; i < 1025; ++i)
{
y = q[i];
x = y;
q[i] = y * 2;
s = q[i] + 3;
t = q[i] + 6;
}
}
__attribute__((noipa)) void
S::bar (short &x, int &y)
{
#pragma omp simd linear (x) linear (s, t: 2) private (y)
for (int i = 0; i < 1025; ++i)
{
y = p[i];
x += y - 2 * i + 1;
p[i] = y * 2;
s += 2 * y - 4 * i + 2;
t += 2 * y - 4 * i + 2;
}
}
__attribute__((noipa)) void
S::baz (short &x, int &y)
{
int *q = this->p;
#pragma omp simd lastprivate (x, s, t) private (y) if (simd: 0)
for (int i = 0; i < 1025; ++i)
{
y = q[i];
x = y;
q[i] = y * 2;
s = q[i] + 3;
t = q[i] + 6;
}
}
__attribute__((noipa)) void
S::qux (short &x, int &y)
{
#pragma omp simd linear (x) linear (s, t: 2) private (y) simdlen (1)
for (int i = 0; i < 1025; ++i)
{
y = p[i];
x += y - 2 * i + 1;
p[i] = y * 2;
s += 2 * y - 4 * i + 2;
t += 2 * y - 4 * i + 2;
}
}
int
main ()
{
short x;
int a[1025], y;
check_vect ();
S s = a;
for (int i = 0; i < 1025; ++i)
{
a[i] = i;
asm volatile ("" : "+g" (i));
}
s.foo (x, y);
if (x != 1024 || s.s != 2051 || s.t != 2054)
abort ();
for (int i = 0; i < 1025; ++i)
if (a[i] != 2 * i)
abort ();
s.bar (x, y);
if (x != 2049 || s.s != 4101 || s.t != 4104)
abort ();
for (int i = 0; i < 1025; ++i)
if (a[i] != 4 * i)
abort ();
else
a[i] = i;
s.baz (x, y);
if (x != 1024 || s.s != 2051 || s.t != 2054)
abort ();
for (int i = 0; i < 1025; ++i)
if (a[i] != 2 * i)
abort ();
s.qux (x, y);
if (x != 2049 || s.s != 4101 || s.t != 4104)
abort ();
for (int i = 0; i < 1025; ++i)
if (a[i] != 4 * i)
abort ();
}