Hi!

While starting to work on OpenMP 4.0 Fortran stuff, I've noticed
some issues in C/C++ too.
One problem is that when some variable other than the iteration var
is linear on a combined for simd or parallel for simd loop, we weren't
adding a barrier between read of the initial value and store of the final
value.  Fixed by making such vars firstprivate+lastprivate on the
omp for loop.
The second issue is that if there are lastprivate vars on combined for simd
loop, the outer assignment on last iteration was keyed on some fd->loop.v
iterator value which hasn't been ever assigned to.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
committed to trunk/4.9.

2014-05-02  Jakub Jelinek  <ja...@redhat.com>

        * gimplify.c (gimplify_adjust_omp_clauses_1): Handle
        GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE.
        (gimplify_adjust_omp_clauses): Simd region is never
        directly nested in combined parallel.  Instead, for linear
        with copyin/copyout, if in combined for simd loop, make decl
        firstprivate/lastprivate on OMP_FOR.
        * omp-low.c (expand_omp_for_generic, expand_omp_for_static_nochunk,
        expand_omp_for_static_chunk): When setting endvar, also set
        fd->loop.v to the same value.
libgomp/
        * testsuite/libgomp.c/simd-10.c: New test.
        * testsuite/libgomp.c/simd-11.c: New test.
        * testsuite/libgomp.c/simd-12.c: New test.
        * testsuite/libgomp.c/simd-13.c: New test.

--- gcc/gimplify.c.jj   2014-04-30 19:06:11.000000000 +0200
+++ gcc/gimplify.c      2014-05-02 11:38:07.908463543 +0200
@@ -6294,9 +6294,17 @@ gimplify_adjust_omp_clauses_1 (splay_tre
          OMP_CLAUSE_CHAIN (clause) = nc;
        }
     }
+  if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
+    {
+      tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
+      OMP_CLAUSE_DECL (nc) = decl;
+      OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
+      OMP_CLAUSE_CHAIN (nc) = *list_p;
+      OMP_CLAUSE_CHAIN (clause) = nc;
+      lang_hooks.decls.omp_finish_clause (nc);
+    }
   *list_p = clause;
   lang_hooks.decls.omp_finish_clause (clause);
-
   return 0;
 }
 
@@ -6335,18 +6343,17 @@ gimplify_adjust_omp_clauses (tree *list_
              if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
                  && ctx->outer_context
                  && !(OMP_CLAUSE_LINEAR_NO_COPYIN (c)
-                      && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
-                 && !is_global_var (decl))
+                      && OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
                {
-                 if (ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
+                 if (ctx->outer_context->combined_loop
+                     && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
                    {
                      n = splay_tree_lookup (ctx->outer_context->variables,
                                             (splay_tree_key) decl);
                      if (n == NULL
                          || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
                        {
-                         int flags = OMP_CLAUSE_LINEAR_NO_COPYIN (c)
-                                     ? GOVD_LASTPRIVATE : GOVD_SHARED;
+                         int flags = GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE;
                          if (n == NULL)
                            omp_add_variable (ctx->outer_context, decl,
                                              flags | GOVD_SEEN);
@@ -6354,7 +6361,7 @@ gimplify_adjust_omp_clauses (tree *list_
                            n->value |= flags | GOVD_SEEN;
                        }
                    }
-                 else
+                 else if (!is_global_var (decl))
                    omp_notice_variable (ctx->outer_context, decl, true);
                }
            }
--- gcc/omp-low.c.jj    2014-04-30 09:13:22.000000000 +0200
+++ gcc/omp-low.c       2014-05-01 15:18:05.368771615 +0200
@@ -5584,6 +5584,12 @@ expand_omp_for_generic (struct omp_regio
     {
       stmt = gimple_build_assign (endvar, iend);
       gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
+      if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (iend)))
+       stmt = gimple_build_assign (fd->loop.v, iend);
+      else
+       stmt = gimple_build_assign_with_ops (NOP_EXPR, fd->loop.v, iend,
+                                            NULL_TREE);
+      gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
     }
   if (fd->collapse > 1)
     expand_omp_for_init_vars (fd, &gsi, counts, inner_stmt, startvar);
@@ -6000,6 +6006,12 @@ expand_omp_for_static_nochunk (struct om
     {
       stmt = gimple_build_assign (endvar, e);
       gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
+      if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (e)))
+       stmt = gimple_build_assign (fd->loop.v, e);
+      else
+       stmt = gimple_build_assign_with_ops (NOP_EXPR, fd->loop.v, e,
+                                            NULL_TREE);
+      gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
     }
   if (fd->collapse > 1)
     expand_omp_for_init_vars (fd, &gsi, counts, inner_stmt, startvar);
@@ -6385,6 +6397,12 @@ expand_omp_for_static_chunk (struct omp_
     {
       stmt = gimple_build_assign (endvar, e);
       gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
+      if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (e)))
+       stmt = gimple_build_assign (fd->loop.v, e);
+      else
+       stmt = gimple_build_assign_with_ops (NOP_EXPR, fd->loop.v, e,
+                                            NULL_TREE);
+      gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
     }
   if (fd->collapse > 1)
     expand_omp_for_init_vars (fd, &si, counts, inner_stmt, startvar);
--- libgomp/testsuite/libgomp.c/simd-10.c.jj    2014-05-01 14:09:25.716138836 
+0200
+++ libgomp/testsuite/libgomp.c/simd-10.c       2014-05-01 14:09:44.081053684 
+0200
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+int s = 0, i, u;
+
+void
+foo ()
+{
+  #pragma omp for simd schedule(static, 32) reduction(+:s) lastprivate(u)
+  for (i = 0; i < 128; i++)
+    {
+      s++;
+      u = i;
+    }
+  if (i != 128 || s != 128 || u != 127)
+    __builtin_abort ();
+}
+
+int
+main ()
+{
+  foo ();
+  return 0;
+}
--- libgomp/testsuite/libgomp.c/simd-11.c.jj    2014-05-01 14:09:28.547127103 
+0200
+++ libgomp/testsuite/libgomp.c/simd-11.c       2014-05-01 14:09:52.813014645 
+0200
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+int s = 0, i, j, u;
+
+void
+foo ()
+{
+  #pragma omp for simd schedule(static, 32) reduction(+:s) lastprivate(u) 
collapse(2)
+  for (i = 0; i < 16; i++)
+    for (j = 0; j < 16; j++)
+      {
+       s++;
+       u = i + j;
+      }
+  if (i != 16 || j != 16 || s != 256 || u != 30)
+    __builtin_abort ();
+}
+
+int
+main ()
+{
+  foo ();
+  return 0;
+}
--- libgomp/testsuite/libgomp.c/simd-12.c.jj    2014-05-02 11:41:08.481513881 
+0200
+++ libgomp/testsuite/libgomp.c/simd-12.c       2014-05-02 11:43:12.999852945 
+0200
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+int
+main ()
+{
+  int k = 0, i, s = 0;
+  #pragma omp parallel
+  #pragma omp for simd linear(k : 3) reduction(+: s) schedule (static, 16)
+  for (i = 0; i < 128; i++)
+    {
+      k = k + 3;
+      s = s + k;
+    }
+  if (s != 128 * 129 / 2 * 3) __builtin_abort ();
+  return 0;
+}
--- libgomp/testsuite/libgomp.c/simd-13.c.jj    2014-03-19 15:57:57.735114622 
+0100
+++ libgomp/testsuite/libgomp.c/simd-13.c       2014-05-02 13:55:25.184041803 
+0200
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+int
+main ()
+{
+  int k = 0, i, s = 0;
+  #pragma omp parallel for simd linear(k : 3) reduction(+: s) schedule 
(static, 16)
+  for (i = 0; i < 128; i++)
+    {
+      k = k + 3;
+      s = s + k;
+    }
+  if (s != 128 * 129 / 2 * 3) __builtin_abort ();
+  return 0;
+}

        Jakub

Reply via email to