omp-low.c (lower_rec_input_clauses): Force max_vf if is_simd and on privatization...
authorJakub Jelinek <jakub@redhat.com>
Wed, 5 Jun 2019 07:36:30 +0000 (09:36 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 5 Jun 2019 07:36:30 +0000 (09:36 +0200)
* 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

gcc/ChangeLog
gcc/omp-low.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/vect/simd-1.cc [new file with mode: 0644]

index 401ba9c58f91fe0f1a04976eba3a6548e5e2dd1b..0d47c351e6fc38d5ea5200c0a78e0dba621f7794 100644 (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
index 8fb68a19b0c2f6ae74f6ea4a41918a2bdd410f70..8ec8f09f20890114b9b70e9dd554aef23239f853 100644 (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);
index 0de9ad902ce54ce74da1900af24e8c1f3b664c26..c4293bb0ef62790209240c8c71f0235dc3cc21f9 100644 (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
diff --git a/gcc/testsuite/g++.dg/vect/simd-1.cc b/gcc/testsuite/g++.dg/vect/simd-1.cc
new file mode 100644 (file)
index 0000000..76ce45d
--- /dev/null
@@ -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 ();
+}