Commit 9ea2bfca by Jakub Jelinek Committed by Jakub Jelinek

omp-low.c (lower_rec_input_clauses): Force max_vf if is_simd and on…

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
parent 5259a047
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> 2019-06-05 Hongtao Liu <hongtao.liu@intel.com>
PR target/89803 PR target/89803
......
...@@ -3831,12 +3831,24 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, ...@@ -3831,12 +3831,24 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
case OMP_CLAUSE_LASTPRIVATE: case OMP_CLAUSE_LASTPRIVATE:
if (is_variable_sized (OMP_CLAUSE_DECL (c))) if (is_variable_sized (OMP_CLAUSE_DECL (c)))
sctx.max_vf = 1; 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; break;
case OMP_CLAUSE_REDUCTION: case OMP_CLAUSE_REDUCTION:
case OMP_CLAUSE_IN_REDUCTION: case OMP_CLAUSE_IN_REDUCTION:
if (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF if (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
|| is_variable_sized (OMP_CLAUSE_DECL (c))) || is_variable_sized (OMP_CLAUSE_DECL (c)))
sctx.max_vf = 1; 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; break;
case OMP_CLAUSE_IF: case OMP_CLAUSE_IF:
if (integer_zerop (OMP_CLAUSE_IF_EXPR (c))) if (integer_zerop (OMP_CLAUSE_IF_EXPR (c)))
...@@ -4665,8 +4677,8 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, ...@@ -4665,8 +4677,8 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
/* For reduction in SIMD loop, defer adding the /* For reduction in SIMD loop, defer adding the
initialization of the reference, because if we decide initialization of the reference, because if we decide
to use SIMD array for it, the initilization could cause to use SIMD array for it, the initilization could cause
expansion ICE. */ expansion ICE. Ditto for other privatization clauses. */
if (c_kind == OMP_CLAUSE_REDUCTION && is_simd) if (is_simd)
x = NULL_TREE; x = NULL_TREE;
else else
{ {
...@@ -4777,10 +4789,21 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, ...@@ -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); tree y = lang_hooks.decls.omp_clause_dtor (c, new_var);
if ((TREE_ADDRESSABLE (new_var) || nx || y if ((TREE_ADDRESSABLE (new_var) || nx || y
|| OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE || 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, && lower_rec_simd_input_clauses (new_var, ctx, &sctx,
ivar, lvar)) 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) if (nx)
x = lang_hooks.decls.omp_clause_default_ctor x = lang_hooks.decls.omp_clause_default_ctor
(c, unshare_expr (ivar), x); (c, unshare_expr (ivar), x);
...@@ -4838,6 +4861,24 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, ...@@ -4838,6 +4861,24 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
} }
break; 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) if (nx)
gimplify_and_add (nx, ilist); gimplify_and_add (nx, ilist);
...@@ -4925,6 +4966,28 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, ...@@ -4925,6 +4966,28 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
if (OMP_CLAUSE_LINEAR_ARRAY (c)) 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 x = lang_hooks.decls.omp_clause_linear_ctor
(c, new_var, x, t); (c, new_var, x, t);
gimplify_and_add (x, ilist); gimplify_and_add (x, ilist);
...@@ -4939,10 +5002,20 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, ...@@ -4939,10 +5002,20 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
} }
if ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LINEAR 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, && lower_rec_simd_input_clauses (new_var, ctx, &sctx,
ivar, lvar)) 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) if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR)
{ {
tree iv = create_tmp_var (TREE_TYPE (new_var)); 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, ...@@ -4977,6 +5050,24 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
} }
break; 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 x = lang_hooks.decls.omp_clause_copy_ctor
(c, unshare_expr (new_var), x); (c, unshare_expr (new_var), x);
......
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> 2019-06-05 Hongtao Liu <hongtao.liu@intel.com>
PR target/89803 PR target/89803
......
// { 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 ();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment