From 9ea2bfca6a3fd80f14d24557f71efaafae3846a9 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 5 Jun 2019 09:36:30 +0200 Subject: [PATCH] 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) : 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 --- gcc/ChangeLog | 11 +++ gcc/omp-low.c | 99 +++++++++++++++++++++++- gcc/testsuite/ChangeLog | 4 + gcc/testsuite/g++.dg/vect/simd-1.cc | 114 ++++++++++++++++++++++++++++ 4 files changed, 224 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/vect/simd-1.cc diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 401ba9c58f9..0d47c351e6f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2019-06-05 Jakub Jelinek + + * 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) : + 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 PR target/89803 diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 8fb68a19b0c..8ec8f09f208 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0de9ad902ce..c4293bb0ef6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-06-05 Jakub Jelinek + + * g++.dg/vect/simd-1.cc: New test. + 2019-06-05 Hongtao Liu PR target/89803 diff --git a/gcc/testsuite/g++.dg/vect/simd-1.cc b/gcc/testsuite/g++.dg/vect/simd-1.cc new file mode 100644 index 00000000000..76ce45d939d --- /dev/null +++ b/gcc/testsuite/g++.dg/vect/simd-1.cc @@ -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 (); +} -- 2.30.2