Hi!

I've committed following fix for various OpenMP gimplification and lowering
issues with privatization of C++ references to VLAs, after
bootstrapping/regtesting it on x86_64-linux and i686-linux.

2016-03-02  Jakub Jelinek  <ja...@redhat.com>

        PR libgomp/69555
        * gimplify.c (gimplify_decl_expr): For decls with REFERENCE_TYPE, also
        gimplify_type_sizes the type they refer to.
        (omp_notice_variable): Handle reference vars to VLAs.
        * omp-low.c (lower_omp_target): Emit setup of OMP_CLAUSE_PRIVATE 
reference
        to VLA decls in the second pass instead of first pass.

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

--- gcc/gimplify.c.jj   2016-03-02 14:08:00.714169515 +0100
+++ gcc/gimplify.c      2016-03-02 16:59:18.466647210 +0100
@@ -1436,14 +1436,22 @@ gimplify_decl_expr (tree *stmt_p, gimple
   if ((TREE_CODE (decl) == TYPE_DECL
        || TREE_CODE (decl) == VAR_DECL)
       && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
-    gimplify_type_sizes (TREE_TYPE (decl), seq_p);
+    {
+      gimplify_type_sizes (TREE_TYPE (decl), seq_p);
+      if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
+       gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
+    }
 
   /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
      in case its size expressions contain problematic nodes like CALL_EXPR.  */
   if (TREE_CODE (decl) == TYPE_DECL
       && DECL_ORIGINAL_TYPE (decl)
       && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
-    gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
+    {
+      gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
+      if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
+       gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
+    }
 
   if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
     {
@@ -6264,16 +6272,30 @@ omp_notice_variable (struct gimplify_omp
 
   if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
       && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
-      && DECL_SIZE (decl)
-      && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
+      && DECL_SIZE (decl))
     {
-      splay_tree_node n2;
-      tree t = DECL_VALUE_EXPR (decl);
-      gcc_assert (TREE_CODE (t) == INDIRECT_REF);
-      t = TREE_OPERAND (t, 0);
-      gcc_assert (DECL_P (t));
-      n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
-      n2->value |= GOVD_SEEN;
+      if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
+       {
+         splay_tree_node n2;
+         tree t = DECL_VALUE_EXPR (decl);
+         gcc_assert (TREE_CODE (t) == INDIRECT_REF);
+         t = TREE_OPERAND (t, 0);
+         gcc_assert (DECL_P (t));
+         n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
+         n2->value |= GOVD_SEEN;
+       }
+      else if (lang_hooks.decls.omp_privatize_by_reference (decl)
+              && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
+              && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
+                  != INTEGER_CST))
+       {
+         splay_tree_node n2;
+         tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
+         gcc_assert (DECL_P (t));
+         n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
+         if (n2)
+           n2->value |= GOVD_SEEN;
+       }
     }
 
   shared = ((flags | n->value) & GOVD_SHARED) != 0;
--- gcc/omp-low.c.jj    2016-03-02 14:07:55.279244149 +0100
+++ gcc/omp-low.c       2016-03-02 16:41:24.916205613 +0100
@@ -16472,13 +16472,7 @@ lower_omp_target (gimple_stmt_iterator *
                    x = build_fold_addr_expr_loc (clause_loc, x);
                  }
                else
-                 {
-                   tree atmp
-                     = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
-                   tree rtype = TREE_TYPE (TREE_TYPE (new_var));
-                   tree al = size_int (TYPE_ALIGN (rtype));
-                   x = build_call_expr_loc (clause_loc, atmp, 2, x, al);
-                 }
+                 break;
 
                x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
                gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
@@ -16545,7 +16539,8 @@ lower_omp_target (gimple_stmt_iterator *
          }
       /* Handle GOMP_MAP_FIRSTPRIVATE_{POINTER,REFERENCE} in second pass,
         so that firstprivate vars holding OMP_CLAUSE_SIZE if needed
-        are already handled.  */
+        are already handled.  Similarly OMP_CLAUSE_PRIVATE for VLAs
+        or references to VLAs.  */
       for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
        switch (OMP_CLAUSE_CODE (c))
          {
@@ -16687,6 +16682,27 @@ lower_omp_target (gimple_stmt_iterator *
                gimple_seq_add_stmt (&new_body,
                                     gimple_build_assign (new_pvar, x));
              }
+           else if (is_reference (var) && !is_gimple_omp_oacc (ctx->stmt))
+             {
+               location_t clause_loc = OMP_CLAUSE_LOCATION (c);
+               tree new_var = lookup_decl (var, ctx);
+               tree x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
+               if (TREE_CONSTANT (x))
+                 break;
+               else
+                 {
+                   tree atmp
+                     = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
+                   tree rtype = TREE_TYPE (TREE_TYPE (new_var));
+                   tree al = size_int (TYPE_ALIGN (rtype));
+                   x = build_call_expr_loc (clause_loc, atmp, 2, x, al);
+                 }
+
+               x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
+               gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
+               gimple_seq_add_stmt (&new_body,
+                                    gimple_build_assign (new_var, x));
+             }
            break;
          }
 
--- libgomp/testsuite/libgomp.c++/pr69555-1.C.jj        2016-03-02 
16:56:09.442214952 +0100
+++ libgomp/testsuite/libgomp.c++/pr69555-1.C   2016-03-02 16:56:09.442214952 
+0100
@@ -0,0 +1,114 @@
+// PR libgomp/69555
+// { dg-do run }
+
+#include <omp.h>
+
+__attribute__((noinline, noclone)) void
+f1 (int y)
+{
+  int a[y - 2];
+  int (&c)[y - 2] = a;
+  c[0] = 111;
+  int e = 0;
+
+  #pragma omp parallel private (c) num_threads (4) reduction (+:e)
+  {
+    int v = omp_get_thread_num ();
+    for (int i = 0; i < y - 2; i++)
+      c[i] = i + v;
+    #pragma omp barrier
+    for (int i = 0; i < y - 2; i++)
+      if (c[i] != i + v)
+       e++;
+  }
+  if (c[0] != 111 || e)
+    __builtin_abort ();
+}
+
+__attribute__((noinline, noclone)) void
+f2 (int y)
+{
+  int a[y - 2];
+  int (&c)[y - 2] = a;
+  c[0] = 111;
+
+  #pragma omp task private (c)
+  {
+    int v = omp_get_thread_num ();
+    for (int i = 0; i < y - 2; i++)
+      c[i] = i + v;
+    asm volatile ("" : : "r" (&c[0]) : "memory");
+    for (int i = 0; i < y - 2; i++)
+      if (c[i] != i + v)
+       __builtin_abort ();
+  }
+  if (c[0] != 111)
+    __builtin_abort ();
+}
+
+__attribute__((noinline, noclone)) void
+f3 (int y)
+{
+  int a[y - 2];
+  int (&c)[y - 2] = a;
+  for (int i = 0; i < y - 2; i++)
+    c[i] = i + 4;
+
+  #pragma omp parallel firstprivate (c) num_threads (4)
+  {
+    int v = omp_get_thread_num ();
+    for (int i = 0; i < y - 2; i++)
+      {
+       if (c[i] != i + 4)
+         __builtin_abort ();
+       c[i] = i + v;
+      }
+    #pragma omp barrier
+    for (int i = 0; i < y - 2; i++)
+      if (c[i] != i + v)
+       __builtin_abort ();
+  }
+  for (int i = 0; i < y - 2; i++)
+    if (c[i] != i + 4)
+      __builtin_abort ();
+}
+
+__attribute__((noinline, noclone)) void
+f4 (int y)
+{
+  int a[y - 2];
+  int (&c)[y - 2] = a;
+  for (int i = 0; i < y - 2; i++)
+    c[i] = i + 4;
+
+  #pragma omp task firstprivate (c)
+  {
+    int v = omp_get_thread_num ();
+    for (int i = 0; i < y - 2; i++)
+      {
+       if (c[i] != i + 4)
+         __builtin_abort ();
+       c[i] = i + v;
+      }
+    asm volatile ("" : : "r" (&c[0]) : "memory");
+    for (int i = 0; i < y - 2; i++)
+      if (c[i] != i + v)
+       __builtin_abort ();
+  }
+  for (int i = 0; i < y - 2; i++)
+    if (c[i] != i + 4)
+      __builtin_abort ();
+}
+
+int
+main ()
+{
+  f1 (6);
+  f3 (6);
+  #pragma omp parallel num_threads (4)
+  {
+    f2 (6);
+    f4 (6);
+  }
+  return 0;
+}
--- libgomp/testsuite/libgomp.c++/pr69555-2.C.jj        2016-03-02 
16:56:09.442214952 +0100
+++ libgomp/testsuite/libgomp.c++/pr69555-2.C   2016-03-02 16:56:09.442214952 
+0100
@@ -0,0 +1,58 @@
+// PR libgomp/69555
+// { dg-do run }
+
+__attribute__((noinline, noclone)) void
+f1 (int y)
+{
+  int a[y - 2];
+  int (&c)[y - 2] = a;
+  for (int i = 0; i < y - 2; i++)
+    c[i] = i + 4;
+
+  #pragma omp target firstprivate (c)
+  {
+    for (int i = 0; i < y - 2; i++)
+      {
+       if (c[i] != i + 4)
+         __builtin_abort ();
+       c[i] = i + 9;
+      }
+    asm volatile ("" : : "r" (&c[0]) : "memory");
+    for (int i = 0; i < y - 2; i++)
+      if (c[i] != i + 9)
+       __builtin_abort ();
+  }
+  for (int i = 0; i < y - 2; i++)
+    if (c[i] != i + 4)
+      __builtin_abort ();
+}
+
+__attribute__((noinline, noclone)) void
+f2 (int y)
+{
+  int a[y - 2];
+  int (&c)[y - 2] = a;
+  for (int i = 0; i < y - 2; i++)
+    c[i] = i + 4;
+
+  #pragma omp target private (c)
+  {
+    for (int i = 0; i < y - 2; i++)
+      c[i] = i + 9;
+    asm volatile ("" : : "r" (&c[0]) : "memory");
+    for (int i = 0; i < y - 2; i++)
+      if (c[i] != i + 9)
+       __builtin_abort ();
+  }
+  for (int i = 0; i < y - 2; i++)
+    if (c[i] != i + 4)
+      __builtin_abort ();
+}
+
+int
+main ()
+{
+  f1 (6);
+  f2 (6);
+  return 0;
+}

        Jakub

Reply via email to