omp-low.c (lower_rec_input_clauses): Handle references properly in inscan clauses.
authorJakub Jelinek <jakub@redhat.com>
Wed, 19 Jun 2019 08:32:09 +0000 (10:32 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 19 Jun 2019 08:32:09 +0000 (10:32 +0200)
* omp-low.c (lower_rec_input_clauses): Handle references properly
in inscan clauses.
(lower_omp_scan): Likewise.
cp/
* cp-gimplify.c (cp_genericize_r): Handle OMP_CLAUSE_{IN,EX}CLUSIVE
like OMP_CLAUSE_SHARED.
testsuite/
* g++.dg/vect/simd-3.cc: New test.
* g++.dg/vect/simd-4.cc: New test.
* g++.dg/vect/simd-5.cc: New test.

From-SVN: r272471

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/cp-gimplify.c
gcc/omp-low.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/vect/simd-3.cc [new file with mode: 0644]
gcc/testsuite/g++.dg/vect/simd-4.cc [new file with mode: 0644]
gcc/testsuite/g++.dg/vect/simd-5.cc [new file with mode: 0644]

index 217b0097062fa8b640ca151e1c1760be9a937fb0..7d337bcab3b15011e319df8c3aeea4a7edf7209c 100644 (file)
@@ -1,3 +1,9 @@
+2019-06-19  Jakub Jelinek  <jakub@redhat.com>
+
+       * omp-low.c (lower_rec_input_clauses): Handle references properly
+       in inscan clauses.
+       (lower_omp_scan): Likewise.
+
 2019-06-19  Kugan Vivekanandarajah  <kugan.vivekanandarajah@linaro.org>
 
        * tree-ssa-address.c (preferred_mem_scale_factor): Handle when
index 7bd47cf4b569f8f9f85e0dd31d6d9abb7edee280..f5dab5493adfb299b3908228788497e5b1ab822f 100644 (file)
@@ -1,3 +1,8 @@
+2019-06-19  Jakub Jelinek  <jakub@redhat.com>
+
+       * cp-gimplify.c (cp_genericize_r): Handle OMP_CLAUSE_{IN,EX}CLUSIVE
+       like OMP_CLAUSE_SHARED.
+
 2019-06-18  Jason Merrill  <jason@redhat.com>
 
        * constexpr.c (cxx_eval_store_expression): Delay target evaluation.
index 7b9607dde1708e2ad8d5dcce721ed70d6e024390..bce01f5098ebd1b3c67324afab8e100709eb18fa 100644 (file)
@@ -1238,6 +1238,8 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
        case OMP_CLAUSE_FIRSTPRIVATE:
        case OMP_CLAUSE_COPYIN:
        case OMP_CLAUSE_COPYPRIVATE:
+       case OMP_CLAUSE_INCLUSIVE:
+       case OMP_CLAUSE_EXCLUSIVE:
          /* Don't dereference an invisiref in OpenMP clauses.  */
          if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
            *walk_subtrees = 0;
index b0f1d94abf73f85bf157bb88e4f764720cb82d97..ba85b1914c075afd3100633cfa54529971ff6881 100644 (file)
@@ -5238,10 +5238,13 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
                              if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
                                {
                                  tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
-                                 x = DECL_VALUE_EXPR (new_var);
-                                 SET_DECL_VALUE_EXPR (new_var, nv);
+                                 x = DECL_VALUE_EXPR (new_vard);
+                                 tree vexpr = nv;
+                                 if (new_vard != new_var)
+                                   vexpr = build_fold_addr_expr (nv);
+                                 SET_DECL_VALUE_EXPR (new_vard, vexpr);
                                  lower_omp (&tseq, ctx);
-                                 SET_DECL_VALUE_EXPR (new_var, x);
+                                 SET_DECL_VALUE_EXPR (new_vard, x);
                                  gimple_seq_add_seq (ilist, tseq);
                                  OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
                                }
@@ -5367,20 +5370,23 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
                    {
                      if (x)
                        {
-                         tree nv = create_tmp_var_raw (TREE_TYPE (new_vard));
+                         tree nv = create_tmp_var_raw (TREE_TYPE (new_var));
                          gimple_add_tmp_var (nv);
-                         ctx->cb.decl_map->put (new_var, nv);
+                         ctx->cb.decl_map->put (new_vard, nv);
                          x = lang_hooks.decls.omp_clause_default_ctor
                                (c, nv, build_outer_var_ref (var, ctx));
                          gimplify_and_add (x, ilist);
                          if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
                            {
                              tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
-                             SET_DECL_VALUE_EXPR (new_var, nv);
-                             DECL_HAS_VALUE_EXPR_P (new_var) = 1;
+                             tree vexpr = nv;
+                             if (new_vard != new_var)
+                               vexpr = build_fold_addr_expr (nv);
+                             SET_DECL_VALUE_EXPR (new_vard, vexpr);
+                             DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
                              lower_omp (&tseq, ctx);
-                             SET_DECL_VALUE_EXPR (new_var, NULL_TREE);
-                             DECL_HAS_VALUE_EXPR_P (new_var) = 0;
+                             SET_DECL_VALUE_EXPR (new_vard, NULL_TREE);
+                             DECL_HAS_VALUE_EXPR_P (new_vard) = 0;
                              gimple_seq_add_seq (ilist, tseq);
                            }
                          OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
@@ -5524,10 +5530,12 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
                      gimplify_assign (ref, x, &llist[1]);
 
                    }
-                 else if (rvarp == NULL)
+                 else
                    {
                      if (omp_is_reference (var) && is_simd)
                        handle_simd_reference (clause_loc, new_vard, ilist);
+                     if (rvarp)
+                       break;
                      gimplify_assign (new_var, x, ilist);
                      if (is_simd)
                        {
@@ -8587,14 +8595,26 @@ lower_omp_scan (gimple_stmt_iterator *gsi_p, omp_context *ctx)
        if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
            && OMP_CLAUSE_REDUCTION_INSCAN (c))
          {
+           location_t clause_loc = OMP_CLAUSE_LOCATION (c);
            tree var = OMP_CLAUSE_DECL (c);
            tree new_var = lookup_decl (var, octx);
            tree val = new_var;
            tree var2 = NULL_TREE;
            tree var3 = NULL_TREE;
-           if (DECL_HAS_VALUE_EXPR_P (new_var))
+           tree new_vard = new_var;
+           if (omp_is_reference (var))
+             {
+               new_var = build_simple_mem_ref_loc (clause_loc, new_var);
+               val = new_var;
+             }
+           if (DECL_HAS_VALUE_EXPR_P (new_vard))
              {
-               val = DECL_VALUE_EXPR (new_var);
+               val = DECL_VALUE_EXPR (new_vard);
+               if (omp_is_reference (var))
+                 {
+                   gcc_assert (TREE_CODE (val) == ADDR_EXPR);
+                   val = TREE_OPERAND (val, 0);
+                 }
                if (TREE_CODE (val) == ARRAY_REF
                    && VAR_P (TREE_OPERAND (val, 0)))
                  {
@@ -8618,14 +8638,15 @@ lower_omp_scan (gimple_stmt_iterator *gsi_p, omp_context *ctx)
                          var2 = val;
                      }
                  }
+               gcc_assert (var2);
              }
            else
              {
                var2 = build_outer_var_ref (var, octx);
                if (input_phase && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
                  {
-                   var3 = maybe_lookup_decl (new_var, octx);
-                   if (var3 == new_var)
+                   var3 = maybe_lookup_decl (new_vard, octx);
+                   if (var3 == new_vard)
                      var3 = NULL_TREE;
                  }
              }
@@ -8646,18 +8667,22 @@ lower_omp_scan (gimple_stmt_iterator *gsi_p, omp_context *ctx)
                      {
                        /* Otherwise, assign to it the identity element.  */
                        gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
-                       tree x = (DECL_HAS_VALUE_EXPR_P (new_var)
-                                 ? DECL_VALUE_EXPR (new_var) : NULL_TREE);
                        tree ref = build_outer_var_ref (var, octx);
-                       SET_DECL_VALUE_EXPR (new_var, val);
+                       tree x = (DECL_HAS_VALUE_EXPR_P (new_vard)
+                                 ? DECL_VALUE_EXPR (new_vard) : NULL_TREE);
+                       if (x)
+                         {
+                           if (omp_is_reference (var))
+                             val = build_fold_addr_expr_loc (clause_loc, val);
+                           SET_DECL_VALUE_EXPR (new_vard, val);
+                         }
                        SET_DECL_VALUE_EXPR (placeholder, ref);
                        DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
                        lower_omp (&tseq, octx);
-                       SET_DECL_VALUE_EXPR (new_var, x);
+                       if (x)
+                         SET_DECL_VALUE_EXPR (new_vard, x);
                        SET_DECL_VALUE_EXPR (placeholder, NULL_TREE);
                        DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
-                       if (x == NULL_TREE)
-                         DECL_HAS_VALUE_EXPR_P (new_var) = 0;
                        gimple_seq_add_seq (&before, tseq);
                        OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
                      }
@@ -8665,15 +8690,20 @@ lower_omp_scan (gimple_stmt_iterator *gsi_p, omp_context *ctx)
                else
                  {
                    gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
-                   tree x = (DECL_HAS_VALUE_EXPR_P (new_var)
-                             ? DECL_VALUE_EXPR (new_var) : NULL_TREE);
-                   SET_DECL_VALUE_EXPR (new_var, val);
+                   tree x = (DECL_HAS_VALUE_EXPR_P (new_vard)
+                             ? DECL_VALUE_EXPR (new_vard) : NULL_TREE);
+                   tree vexpr = val;
+                   if (x && omp_is_reference (var))
+                     vexpr = build_fold_addr_expr_loc (clause_loc, val);
+                   if (x)
+                     SET_DECL_VALUE_EXPR (new_vard, vexpr);
                    SET_DECL_VALUE_EXPR (placeholder, var2);
                    DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
                    lower_omp (&tseq, octx);
                    gimple_seq_add_seq (&before, tseq);
                    OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
-                   SET_DECL_VALUE_EXPR (new_var, x);
+                   if (x)
+                     SET_DECL_VALUE_EXPR (new_vard, x);
                    SET_DECL_VALUE_EXPR (placeholder, NULL_TREE);
                    DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
                    x = lang_hooks.decls.omp_clause_assign_op (c, val, var2);
index 72f34d8e6164b34a52afcd425b988e3925f58544..ad8c1ac4fb8589c9c8165486b88146906b6cfb69 100644 (file)
@@ -1,3 +1,9 @@
+2019-06-19  Jakub Jelinek  <jakub@redhat.com>
+
+       * g++.dg/vect/simd-3.cc: New test.
+       * g++.dg/vect/simd-4.cc: New test.
+       * g++.dg/vect/simd-5.cc: New test.
+
 2019-06-19  Jakub Jelinek  <jakub@redhat.com>
 
        * g++.dg/ubsan/pr63956.C: Adjust expected diagnostics.
diff --git a/gcc/testsuite/g++.dg/vect/simd-3.cc b/gcc/testsuite/g++.dg/vect/simd-3.cc
new file mode 100644 (file)
index 0000000..d998171
--- /dev/null
@@ -0,0 +1,120 @@
+// { dg-require-effective-target size32plus }
+// { dg-additional-options "-fopenmp-simd" }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+// { dg-final { scan-tree-dump-times "vectorized \[1-3] loops" 2 "vect" { target i?86-*-* x86_64-*-* } } } */
+
+#include "../../gcc.dg/vect/tree-vect.h"
+
+int r, a[1024], b[1024], q;
+
+__attribute__((noipa)) void
+foo (int *a, int *b, int &r)
+{
+  #pragma omp simd reduction (inscan, +:r)
+  for (int i = 0; i < 1024; i++)
+    {
+      r += a[i];
+      #pragma omp scan inclusive(r)
+      b[i] = r;
+    }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+  int &s = q;
+  q = 0;
+  #pragma omp simd reduction (inscan, +:s)
+  for (int i = 0; i < 1024; i++)
+    {
+      s += 2 * a[i];
+      #pragma omp scan inclusive(s)
+      b[i] = s;
+    }
+  return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b, int &r)
+{
+  #pragma omp simd reduction (inscan, +:r) if (simd: 0)
+  for (int i = 0; i < 1024; i++)
+    {
+      r += a[i];
+      #pragma omp scan inclusive(r)
+      b[i] = r;
+    }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+  int &s = q;
+  q = 0;
+  #pragma omp simd reduction (inscan, +:s) simdlen (1)
+  for (int i = 0; i < 1024; i++)
+    {
+      s += 2 * a[i];
+      #pragma omp scan inclusive(s)
+      b[i] = s;
+    }
+  return s;
+}
+
+int
+main ()
+{
+  int s = 0;
+  check_vect ();
+  for (int i = 0; i < 1024; ++i)
+    {
+      a[i] = i;
+      b[i] = -1;
+      asm ("" : "+g" (i));
+    }
+  foo (a, b, r);
+  if (r != 1024 * 1023 / 2)
+    abort ();
+  for (int i = 0; i < 1024; ++i)
+    {
+      s += i;
+      if (b[i] != s)
+       abort ();
+      else
+       b[i] = 25;
+    }
+  if (bar () != 1024 * 1023)
+    abort ();
+  s = 0;
+  for (int i = 0; i < 1024; ++i)
+    {
+      s += 2 * i;
+      if (b[i] != s)
+       abort ();
+      else
+       b[i] = -1;
+    }
+  r = 0;
+  baz (a, b, r);
+  if (r != 1024 * 1023 / 2)
+    abort ();
+  s = 0;
+  for (int i = 0; i < 1024; ++i)
+    {
+      s += i;
+      if (b[i] != s)
+       abort ();
+      else
+       b[i] = -25;
+    }
+  if (qux () != 1024 * 1023)
+    abort ();
+  s = 0;
+  for (int i = 0; i < 1024; ++i)
+    {
+      s += 2 * i;
+      if (b[i] != s)
+       abort ();
+    }
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/vect/simd-4.cc b/gcc/testsuite/g++.dg/vect/simd-4.cc
new file mode 100644 (file)
index 0000000..8f31989
--- /dev/null
@@ -0,0 +1,122 @@
+// { dg-require-effective-target size32plus }
+// { dg-additional-options "-fopenmp-simd" }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+// { dg-final { scan-tree-dump-times "vectorized \[1-3] loops" 2 "vect" { target i?86-*-* x86_64-*-* } } }
+
+#include "../../gcc.dg/vect/tree-vect.h"
+
+int r, a[1024], b[1024], q;
+
+#pragma omp declare reduction (foo: int: omp_out += omp_in) initializer (omp_priv = 0)
+
+__attribute__((noipa)) void
+foo (int *a, int *b, int &r)
+{
+  #pragma omp simd reduction (inscan, foo:r)
+  for (int i = 0; i < 1024; i++)
+    {
+      r += a[i];
+      #pragma omp scan inclusive(r)
+      b[i] = r;
+    }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+  int &s = q;
+  q = 0;
+  #pragma omp simd reduction (inscan, foo:s)
+  for (int i = 0; i < 1024; i++)
+    {
+      s += 2 * a[i];
+      #pragma omp scan inclusive(s)
+      b[i] = s;
+    }
+  return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b, int &r)
+{
+  #pragma omp simd reduction (inscan, foo:r) if (simd: 0)
+  for (int i = 0; i < 1024; i++)
+    {
+      r += a[i];
+      #pragma omp scan inclusive(r)
+      b[i] = r;
+    }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+  int &s = q;
+  q = 0;
+  #pragma omp simd reduction (inscan, foo:s) simdlen (1)
+  for (int i = 0; i < 1024; i++)
+    {
+      s += 2 * a[i];
+      #pragma omp scan inclusive(s)
+      b[i] = s;
+    }
+  return s;
+}
+
+int
+main ()
+{
+  int s = 0;
+  check_vect ();
+  for (int i = 0; i < 1024; ++i)
+    {
+      a[i] = i;
+      b[i] = -1;
+      asm ("" : "+g" (i));
+    }
+  foo (a, b, r);
+  if (r != 1024 * 1023 / 2)
+    abort ();
+  for (int i = 0; i < 1024; ++i)
+    {
+      s += i;
+      if (b[i] != s)
+       abort ();
+      else
+       b[i] = 25;
+    }
+  if (bar () != 1024 * 1023)
+    abort ();
+  s = 0;
+  for (int i = 0; i < 1024; ++i)
+    {
+      s += 2 * i;
+      if (b[i] != s)
+       abort ();
+      else
+       b[i] = -1;
+    }
+  r = 0;
+  baz (a, b, r);
+  if (r != 1024 * 1023 / 2)
+    abort ();
+  s = 0;
+  for (int i = 0; i < 1024; ++i)
+    {
+      s += i;
+      if (b[i] != s)
+       abort ();
+      else
+       b[i] = -25;
+    }
+  if (qux () != 1024 * 1023)
+    abort ();
+  s = 0;
+  for (int i = 0; i < 1024; ++i)
+    {
+      s += 2 * i;
+      if (b[i] != s)
+       abort ();
+    }
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/vect/simd-5.cc b/gcc/testsuite/g++.dg/vect/simd-5.cc
new file mode 100644 (file)
index 0000000..e975595
--- /dev/null
@@ -0,0 +1,153 @@
+// { dg-require-effective-target size32plus }
+// { dg-additional-options "-fopenmp-simd" }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+// { dg-final { scan-tree-dump-times "vectorized \[1-3] loops" 2 "vect" { xfail *-*-* } } }
+
+#include "../../gcc.dg/vect/tree-vect.h"
+
+struct S {
+  inline S ();
+  inline ~S ();
+  inline S (const S &);
+  inline S & operator= (const S &);
+  int s;
+};
+
+S::S () : s (0)
+{
+}
+
+S::~S ()
+{
+}
+
+S::S (const S &x)
+{
+  s = x.s;
+}
+
+S &
+S::operator= (const S &x)
+{
+  s = x.s;
+  return *this;
+}
+
+static inline void
+ini (S &x)
+{
+  x.s = 0;
+}
+
+S r, a[1024], b[1024];
+
+#pragma omp declare reduction (+: S: omp_out.s += omp_in.s)
+#pragma omp declare reduction (plus: S: omp_out.s += omp_in.s) initializer (ini (omp_priv))
+
+__attribute__((noipa)) void
+foo (S *a, S *b, S &r)
+{
+  #pragma omp simd reduction (inscan, +:r)
+  for (int i = 0; i < 1024; i++)
+    {
+      r.s += a[i].s;
+      #pragma omp scan inclusive(r)
+      b[i] = r;
+    }
+}
+
+__attribute__((noipa)) S
+bar (void)
+{
+  S s;
+  #pragma omp simd reduction (inscan, plus:s)
+  for (int i = 0; i < 1024; i++)
+    {
+      s.s += 2 * a[i].s;
+      #pragma omp scan inclusive(s)
+      b[i] = s;
+    }
+  return s;
+}
+
+__attribute__((noipa)) void
+baz (S *a, S *b, S &r)
+{
+  #pragma omp simd reduction (inscan, +:r) simdlen(1)
+  for (int i = 0; i < 1024; i++)
+    {
+      r.s += a[i].s;
+      #pragma omp scan inclusive(r)
+      b[i] = r;
+    }
+}
+
+__attribute__((noipa)) S
+qux (void)
+{
+  S s;
+  #pragma omp simd if (0) reduction (inscan, plus:s)
+  for (int i = 0; i < 1024; i++)
+    {
+      s.s += 2 * a[i].s;
+      #pragma omp scan inclusive(s)
+      b[i] = s;
+    }
+  return s;
+}
+
+int
+main ()
+{
+  S s;
+  check_vect ();
+  for (int i = 0; i < 1024; ++i)
+    {
+      a[i].s = i;
+      b[i].s = -1;
+      asm ("" : "+g" (i));
+    }
+  foo (a, b, r);
+  if (r.s != 1024 * 1023 / 2)
+    abort ();
+  for (int i = 0; i < 1024; ++i)
+    {
+      s.s += i;
+      if (b[i].s != s.s)
+       abort ();
+      else
+       b[i].s = 25;
+    }
+  if (bar ().s != 1024 * 1023)
+    abort ();
+  s.s = 0;
+  for (int i = 0; i < 1024; ++i)
+    {
+      s.s += 2 * i;
+      if (b[i].s != s.s)
+       abort ();
+    }
+  r.s = 0;
+  baz (a, b, r);
+  if (r.s != 1024 * 1023 / 2)
+    abort ();
+  s.s = 0;
+  for (int i = 0; i < 1024; ++i)
+    {
+      s.s += i;
+      if (b[i].s != s.s)
+       abort ();
+      else
+       b[i].s = 25;
+    }
+  if (qux ().s != 1024 * 1023)
+    abort ();
+  s.s = 0;
+  for (int i = 0; i < 1024; ++i)
+    {
+      s.s += 2 * i;
+      if (b[i].s != s.s)
+       abort ();
+    }
+  return 0;
+}