omp-low.c (lower_rec_input_clauses): For lastprivate conditional references...
authorJakub Jelinek <jakub@redhat.com>
Wed, 5 Jun 2019 07:37:40 +0000 (09:37 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 5 Jun 2019 07:37:40 +0000 (09:37 +0200)
* omp-low.c (lower_rec_input_clauses): For lastprivate conditional
references, lookup in in hash map MEM_REF operand instead of the
MEM_REF itself.
(lower_omp_1): When looking for lastprivate conditional assignments,
handle MEM_REFs with REFERENCE_TYPE operands.

* testsuite/libgomp.c++/lastprivate-conditional-1.C: New test.
* testsuite/libgomp.c++/lastprivate-conditional-2.C: New test.

From-SVN: r271948

gcc/ChangeLog
gcc/omp-low.c
libgomp/ChangeLog
libgomp/testsuite/libgomp.c++/lastprivate-conditional-1.C [new file with mode: 0644]
libgomp/testsuite/libgomp.c++/lastprivate-conditional-2.C [new file with mode: 0644]

index 0d47c351e6fc38d5ea5200c0a78e0dba621f7794..cc706e207b57eab316e3be6106fd636d8ddf36d3 100644 (file)
@@ -1,5 +1,11 @@
 2019-06-05  Jakub Jelinek  <jakub@redhat.com>
 
+       * omp-low.c (lower_rec_input_clauses): For lastprivate conditional
+       references, lookup in in hash map MEM_REF operand instead of the
+       MEM_REF itself.
+       (lower_omp_1): When looking for lastprivate conditional assignments,
+       handle MEM_REFs with REFERENCE_TYPE operands.
+
        * 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
index 8ec8f09f20890114b9b70e9dd554aef23239f853..a7f35ffe416764b777ed30b9a869c3b89626fcbd 100644 (file)
@@ -4818,8 +4818,14 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
                      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
                          && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
                        {
-                         tree v
-                           = *ctx->lastprivate_conditional_map->get (new_var);
+                         tree v = new_var;
+                         if (!DECL_P (v))
+                           {
+                             gcc_assert (TREE_CODE (v) == MEM_REF);
+                             v = TREE_OPERAND (v, 0);
+                             gcc_assert (DECL_P (v));
+                           }
+                         v = *ctx->lastprivate_conditional_map->get (v);
                          tree t = create_tmp_var (TREE_TYPE (v));
                          tree z = build_zero_cst (TREE_TYPE (v));
                          tree orig_v
@@ -10926,6 +10932,11 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
          else if (!up->lastprivate_conditional_map)
            break;
          tree lhs = get_base_address (gimple_assign_lhs (stmt));
+         if (TREE_CODE (lhs) == MEM_REF
+             && DECL_P (TREE_OPERAND (lhs, 0))
+             && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs,
+                                                    0))) == REFERENCE_TYPE)
+           lhs = TREE_OPERAND (lhs, 0);
          if (DECL_P (lhs))
            if (tree *v = up->lastprivate_conditional_map->get (lhs))
              {
index 6371092c117e7929e120e50ab65700dad9724466..2ea937ebb650617375f79d8aeaedcfb6ca634397 100644 (file)
@@ -1,3 +1,8 @@
+2019-06-05  Jakub Jelinek  <jakub@redhat.com>
+
+       * testsuite/libgomp.c++/lastprivate-conditional-1.C: New test.
+       * testsuite/libgomp.c++/lastprivate-conditional-2.C: New test.
+
 2019-06-04  Jakub Jelinek  <jakub@redhat.com>
 
        * testsuite/libgomp.c-c++-common/lastprivate-conditional-7.c: New test.
diff --git a/libgomp/testsuite/libgomp.c++/lastprivate-conditional-1.C b/libgomp/testsuite/libgomp.c++/lastprivate-conditional-1.C
new file mode 100644 (file)
index 0000000..e0ec5d5
--- /dev/null
@@ -0,0 +1,62 @@
+extern "C" void abort ();
+int w;
+struct S { int s, &t; S () : s (0), t (w) {}; void foo (short &); bool bar (int, int); void baz (short &); };
+
+bool
+S::bar (int i, int q)
+{
+  switch (q)
+    {
+    case 0: return (i % 17) == 7;
+    case 1: return (i % 19) == 2;
+    case 2: return (i % 23) == 5;
+    default: abort ();
+    }
+}
+
+void
+S::foo (short &x)
+{
+  #pragma omp for lastprivate (conditional: x, s, t)
+  for (int i = 0; i < 1025; ++i)
+    {
+      if (bar (i, 0))
+       x = i;
+      if (bar (i, 1))
+       s = i + 3;
+      if (bar (i, 2))
+       t = i + 6;
+    }
+}
+
+void
+S::baz (short &x)
+{
+  #pragma omp parallel for lastprivate (conditional: x, s, t) collapse (3)
+  for (int i = 0; i < 15; ++i)
+    for (int j = -4; j < 9; j++)
+      for (int k = 12; k > 7; --k)
+       {
+         int l = (k - 8) + (j + 4) * 5 + i * 13 * 5;
+         if (bar (l, 0))
+           x = l;
+         if (bar (l, 1))
+           s = l + 3;
+         if (bar (l, 2))
+           t = l + 6;
+       }
+}
+
+int
+main ()
+{
+  short x;
+  S s;
+  #pragma omp parallel
+  s.foo (x);
+  if (x != 1010 || s.s != 1012 || s.t != 1023)
+    abort ();
+  s.baz (x);
+  if (x != 959 || s.s != 974 || s.t != 977)
+    abort ();
+}
diff --git a/libgomp/testsuite/libgomp.c++/lastprivate-conditional-2.C b/libgomp/testsuite/libgomp.c++/lastprivate-conditional-2.C
new file mode 100644 (file)
index 0000000..742ef21
--- /dev/null
@@ -0,0 +1,104 @@
+extern "C" void abort ();
+int w;
+struct S {
+  int s, &t;
+  int *p;
+  S (int *x) : s (0), t (w), p(x) {};
+  void foo (short &);
+  void bar (short &);
+  void baz (short &);
+  void qux (short &);
+};
+
+void
+S::foo (short &x)
+{
+  #pragma omp simd lastprivate (conditional: x, s, t)
+  for (int i = 0; i < 1025; ++i)
+    {
+      if (p[i])
+       x = i;
+      if (p[i + 1025])
+       s = i + 3;
+      if (p[i + 2 * 1025])
+       t = i + 6;
+    }
+}
+
+void
+S::bar (short &x)
+{
+  #pragma omp simd lastprivate (conditional: x, s, t) collapse (3) if (0)
+  for (int i = 0; i < 15; ++i)
+    for (int j = -4; j < 9; j++)
+      for (int k = 12; k > 7; --k)
+       {
+         int l = (k - 8) + (j + 4) * 5 + i * 13 * 5;
+         if (p[l])
+           x = l;
+         if (p[l + 1025])
+           s = l + 3;
+         if (p[l + 1025 * 2])
+           t = l + 6;
+       }
+}
+
+void
+S::baz (short &x)
+{
+  #pragma omp parallel for simd lastprivate (conditional: x, s, t) if (simd: 0)
+  for (int i = 0; i < 1025; ++i)
+    {
+      if (p[i])
+       x = i;
+      if (p[i + 1025])
+       s = i + 3;
+      if (p[i + 2 * 1025])
+       t = i + 6;
+    }
+}
+
+void
+S::qux (short &x)
+{
+  #pragma omp for simd lastprivate (conditional: x, s, t) collapse (3) schedule (simd: guided, 8)
+  for (int i = 0; i < 15; ++i)
+    for (int j = -4; j < 9; j++)
+      for (int k = 12; k > 7; --k)
+       {
+         int l = (k - 8) + (j + 4) * 5 + i * 13 * 5;
+         if (p[l])
+           x = l;
+         if (p[l + 1025])
+           s = l + 3;
+         if (p[l + 1025 * 2])
+           t = l + 6;
+       }
+}
+
+int
+main ()
+{
+  short x;
+  int a[3 * 1025];
+  for (int i = 0; i < 1025; ++i)
+    {
+      a[i] = ((i % 17) == 7);
+      a[1025 + i] = ((i % 19) == 2);
+      a[2 * 1025 + i] = ((i % 23) == 5);
+    }
+  S s = a;
+  s.foo (x);
+  if (x != 1010 || s.s != 1012 || s.t != 1023)
+    abort ();
+  s.bar (x);
+  if (x != 959 || s.s != 974 || s.t != 977)
+    abort ();
+  #pragma omp parallel
+  s.baz (x);
+  if (x != 1010 || s.s != 1012 || s.t != 1023)
+    abort ();
+  s.qux (x);
+  if (x != 959 || s.s != 974 || s.t != 977)
+    abort ();
+}