Hi!

This patch fixes various issues with handling lastprivate and linear clauses
and simd collapse > 1 loops.

Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk
and 4.9 branch.

2014-06-24  Jakub Jelinek  <ja...@redhat.com>

        * gimplify.c (gimplify_omp_for): For #pragma omp for simd iterator
        not mentioned in clauses use private clause if the iterator is
        declared in #pragma omp for simd, and when adding lastprivate
        instead, add it to the outer #pragma omp for too.  Diagnose
        if the variable is private in outer context.  For simd collapse > 1
        loops, replace all iterators with temporaries.
        * omp-low.c (lower_rec_input_clauses): Handle LINEAR clause the
        same even in collapse > 1 loops.
gcc/c/
        * c-parser.c (c_parser_omp_for_loop): For
        #pragma omp parallel for simd move lastprivate clause from parallel
        to for rather than simd.
gcc/cp/
        * parser.c (cp_parser_omp_for_loop): For
        #pragma omp parallel for simd move lastprivate clause from parallel
        to for rather than simd.
libgomp/
        * testsuite/libgomp.c/for-2.c: Define SC to static for
        #pragma omp for simd testing.
        * testsuite/libgomp.c/for-2.h (SC): Define if not defined.
        (N(f5), N(f6), N(f7), N(f8), N(f10), N(f12), N(f14)): Use
        SC macro.
        * testsuite/libgomp.c/simd-14.c: New test.
        * testsuite/libgomp.c/simd-15.c: New test.
        * testsuite/libgomp.c/simd-16.c: New test.
        * testsuite/libgomp.c/simd-17.c: New test.
        * testsuite/libgomp.c++/for-10.C: Define SC to static for
        #pragma omp for simd testing.
        * testsuite/libgomp.c++/simd10.C: New test.
        * testsuite/libgomp.c++/simd11.C: New test.
        * testsuite/libgomp.c++/simd12.C: New test.
        * testsuite/libgomp.c++/simd13.C: New test.

--- gcc/gimplify.c.jj   2014-06-20 23:31:49.000000000 +0200
+++ gcc/gimplify.c      2014-06-23 16:55:19.153679764 +0200
@@ -6810,6 +6810,31 @@ gimplify_omp_for (tree *expr_p, gimple_s
              bool lastprivate
                = (!has_decl_expr
                   || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
+             if (lastprivate
+                 && gimplify_omp_ctxp->outer_context
+                 && gimplify_omp_ctxp->outer_context->region_type
+                    == ORT_WORKSHARE
+                 && gimplify_omp_ctxp->outer_context->combined_loop
+                 && !gimplify_omp_ctxp->outer_context->distribute)
+               {
+                 struct gimplify_omp_ctx *outer
+                   = gimplify_omp_ctxp->outer_context;
+                 n = splay_tree_lookup (outer->variables,
+                                        (splay_tree_key) decl);
+                 if (n != NULL
+                     && (n->value & GOVD_DATA_SHARE_CLASS) == GOVD_LOCAL)
+                   lastprivate = false;
+                 else if (omp_check_private (outer, decl, false))
+                   error ("lastprivate variable %qE is private in outer "
+                          "context", DECL_NAME (decl));
+                 else
+                   {
+                     omp_add_variable (outer, decl,
+                                       GOVD_LASTPRIVATE | GOVD_SEEN);
+                     if (outer->outer_context)
+                       omp_notice_variable (outer->outer_context, decl, true);
+                   }
+               }
              c = build_omp_clause (input_location,
                                    lastprivate ? OMP_CLAUSE_LASTPRIVATE
                                                : OMP_CLAUSE_PRIVATE);
@@ -6829,10 +6854,13 @@ gimplify_omp_for (tree *expr_p, gimple_s
 
       /* If DECL is not a gimple register, create a temporary variable to act
         as an iteration counter.  This is valid, since DECL cannot be
-        modified in the body of the loop.  */
+        modified in the body of the loop.  Similarly for any iteration vars
+        in simd with collapse > 1 where the iterator vars must be
+        lastprivate.  */
       if (orig_for_stmt != for_stmt)
        var = decl;
-      else if (!is_gimple_reg (decl))
+      else if (!is_gimple_reg (decl)
+              || (simd && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1))
        {
          var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
          TREE_OPERAND (t, 0) = var;
--- gcc/omp-low.c.jj    2014-06-20 23:31:49.000000000 +0200
+++ gcc/omp-low.c       2014-06-23 15:30:08.937060484 +0200
@@ -3421,24 +3421,20 @@ lower_rec_input_clauses (tree clauses, g
                                                OMP_CLAUSE__LOOPTEMP_);
                      gcc_assert (c);
                      tree l = OMP_CLAUSE_DECL (c);
-                     if (fd->collapse == 1)
-                       {
-                         tree n1 = fd->loop.n1;
-                         tree step = fd->loop.step;
-                         tree itype = TREE_TYPE (l);
-                         if (POINTER_TYPE_P (itype))
-                           itype = signed_type_for (itype);
-                         l = fold_build2 (MINUS_EXPR, itype, l, n1);
-                         if (TYPE_UNSIGNED (itype)
-                             && fd->loop.cond_code == GT_EXPR)
-                           l = fold_build2 (TRUNC_DIV_EXPR, itype,
-                                            fold_build1 (NEGATE_EXPR,
-                                                         itype, l),
-                                            fold_build1 (NEGATE_EXPR,
-                                                         itype, step));
-                         else
-                           l = fold_build2 (TRUNC_DIV_EXPR, itype, l, step);
-                       }
+                     tree n1 = fd->loop.n1;
+                     tree step = fd->loop.step;
+                     tree itype = TREE_TYPE (l);
+                     if (POINTER_TYPE_P (itype))
+                       itype = signed_type_for (itype);
+                     l = fold_build2 (MINUS_EXPR, itype, l, n1);
+                     if (TYPE_UNSIGNED (itype)
+                         && fd->loop.cond_code == GT_EXPR)
+                       l = fold_build2 (TRUNC_DIV_EXPR, itype,
+                                        fold_build1 (NEGATE_EXPR, itype, l),
+                                        fold_build1 (NEGATE_EXPR,
+                                                     itype, step));
+                     else
+                       l = fold_build2 (TRUNC_DIV_EXPR, itype, l, step);
                      t = fold_build2 (MULT_EXPR, stept,
                                       fold_convert (stept, l), t);
                      if (POINTER_TYPE_P (TREE_TYPE (x)))
--- gcc/c/c-parser.c.jj 2014-06-16 10:07:15.000000000 +0200
+++ gcc/c/c-parser.c    2014-06-23 14:44:39.357283434 +0200
@@ -11910,8 +11910,17 @@ c_parser_omp_for_loop (location_t loc, c
                        tree l = build_omp_clause (OMP_CLAUSE_LOCATION (*c),
                                                   OMP_CLAUSE_LASTPRIVATE);
                        OMP_CLAUSE_DECL (l) = OMP_CLAUSE_DECL (*c);
-                       OMP_CLAUSE_CHAIN (l) = clauses;
-                       clauses = l;
+                       if (code == OMP_SIMD)
+                         {
+                           OMP_CLAUSE_CHAIN (l)
+                             = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
+                           cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
+                         }
+                       else
+                         {
+                           OMP_CLAUSE_CHAIN (l) = clauses;
+                           clauses = l;
+                         }
                        OMP_CLAUSE_SET_CODE (*c, OMP_CLAUSE_SHARED);
                      }
                  }
--- gcc/cp/parser.c.jj  2014-06-12 23:08:12.000000000 +0200
+++ gcc/cp/parser.c     2014-06-23 15:25:21.756579447 +0200
@@ -29418,9 +29418,17 @@ cp_parser_omp_for_loop (cp_parser *parse
                   change it to shared (decl) in OMP_PARALLEL_CLAUSES.  */
                tree l = build_omp_clause (loc, OMP_CLAUSE_LASTPRIVATE);
                OMP_CLAUSE_DECL (l) = real_decl;
-               OMP_CLAUSE_CHAIN (l) = clauses;
                CP_OMP_CLAUSE_INFO (l) = CP_OMP_CLAUSE_INFO (*c);
-               clauses = l;
+               if (code == OMP_SIMD)
+                 {
+                   OMP_CLAUSE_CHAIN (l) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
+                   cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
+                 }
+               else
+                 {
+                   OMP_CLAUSE_CHAIN (l) = clauses;
+                   clauses = l;
+                 }
                OMP_CLAUSE_SET_CODE (*c, OMP_CLAUSE_SHARED);
                CP_OMP_CLAUSE_INFO (*c) = NULL;
                add_private_clause = false;
--- libgomp/testsuite/libgomp.c++/simd11.C.jj   2014-06-23 17:07:11.361978247 
+0200
+++ libgomp/testsuite/libgomp.c++/simd11.C      2014-06-23 17:07:17.566952046 
+0200
@@ -0,0 +1,6 @@
+// { dg-do run }
+// { dg-options "-O2" }
+// { dg-additional-options "-msse2" { target sse2_runtime } }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+
+#include "../libgomp.c/simd-15.c"
--- libgomp/testsuite/libgomp.c++/simd12.C.jj   2014-06-23 17:07:11.361978247 
+0200
+++ libgomp/testsuite/libgomp.c++/simd12.C      2014-06-23 17:07:23.098917694 
+0200
@@ -0,0 +1,6 @@
+// { dg-do run }
+// { dg-options "-O2" }
+// { dg-additional-options "-msse2" { target sse2_runtime } }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+
+#include "../libgomp.c/simd-16.c"
--- libgomp/testsuite/libgomp.c++/simd10.C.jj   2014-06-23 17:06:20.490245913 
+0200
+++ libgomp/testsuite/libgomp.c++/simd10.C      2014-06-23 17:06:46.683106539 
+0200
@@ -0,0 +1,6 @@
+// { dg-do run }
+// { dg-options "-O2" }
+// { dg-additional-options "-msse2" { target sse2_runtime } }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+
+#include "../libgomp.c/simd-14.c"
--- libgomp/testsuite/libgomp.c++/simd13.C.jj   2014-06-23 17:07:11.361978247 
+0200
+++ libgomp/testsuite/libgomp.c++/simd13.C      2014-06-23 17:07:29.215885447 
+0200
@@ -0,0 +1,6 @@
+// { dg-do run }
+// { dg-options "-O2" }
+// { dg-additional-options "-msse2" { target sse2_runtime } }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+
+#include "../libgomp.c/simd-17.c"
--- libgomp/testsuite/libgomp.c++/for-10.C.jj   2013-10-11 11:23:59.000000000 
+0200
+++ libgomp/testsuite/libgomp.c++/for-10.C      2014-06-23 17:05:49.141412893 
+0200
@@ -19,11 +19,14 @@ extern "C" void abort ();
 #undef F
 #undef G
 
+#undef SC
+#define SC static
 #define F for simd
 #define G f_simd
 #include "../libgomp.c/for-1.h"
 #undef F
 #undef G
+#undef SC
 
 int
 main ()
--- libgomp/testsuite/libgomp.c/simd-15.c.jj    2014-06-23 15:19:00.121579380 
+0200
+++ libgomp/testsuite/libgomp.c/simd-15.c       2014-06-23 15:20:31.286104453 
+0200
@@ -0,0 +1,129 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+static inline void
+foo (int *b, int *i, int *j, int x)
+{
+  *b = *b + x + (*i - *i) + (*j - *j);
+}
+
+int
+main ()
+{
+  int i, j, b, c = 0;
+  i = 4; j = 4; b = 7;
+  #pragma omp simd linear(b:2) reduction(+:c)
+  for (i = 0; i < 64; i++)
+    {
+      c = c + (b != 7 + 2 * i);
+      foo (&b, &i, &j, 2);
+    }
+  if (c || i != 64 || b != 7 + 64 * 2)
+    __builtin_abort ();
+  i = 4; j = 4; b = 7;
+  #pragma omp simd linear(b:3) reduction(+:c)
+  for (i = 0; i < 64; i += 4)
+    {
+      c = c + (b != 7 + i / 4 * 3);
+      foo (&b, &i, &j, 3);
+    }
+  if (c || i != 64 || b != 7 + 16 * 3)
+    __builtin_abort ();
+  i = 4; j = 4; b = 7;
+  #pragma omp simd linear(i) linear(b:2) reduction(+:c)
+  for (i = 0; i < 64; i++)
+    {
+      c = c + (b != 7 + 2 * i);
+      foo (&b, &i, &j, 2);
+    }
+  if (c || i != 64 || b != 7 + 64 * 2)
+    __builtin_abort ();
+  i = 4; j = 4; b = 7;
+  #pragma omp simd linear(i:4) linear(b:3) reduction(+:c)
+  for (i = 0; i < 64; i += 4)
+    {
+      c = c + (b != 7 + i / 4 * 3);
+      foo (&b, &i, &j, 3);
+    }
+  if (c || i != 64 || b != 7 + 16 * 3)
+    __builtin_abort ();
+  i = 4; j = 4; b = 7;
+  #pragma omp simd collapse (2) linear(b:2) reduction(+:c)
+  for (i = 0; i < 8; i++)
+    for (j = 0; j < 8; j++)
+      {
+       c = c + (b != 7 + 2 * j + 2 * 8 * i);
+       foo (&b, &i, &j, 2);
+      }
+  if (c || i != 8 || j != 8 || b != 7 + 64 * 2)
+    __builtin_abort ();
+  i = 4; j = 4; b = 7;
+  #pragma omp simd collapse (2) lastprivate (i, j) linear(b:2) reduction(+:c)
+  for (i = 0; i < 8; i++)
+    for (j = 0; j < 8; j++)
+      {
+       c = c + (b != 7 + 2 * j + 2 * 8 * i);
+       foo (&b, &i, &j, 2);
+      }
+  if (c || i != 8 || j != 8 || b != 7 + 64 * 2)
+    __builtin_abort ();
+  i = 4; j = 4; b = 7;
+  #pragma omp parallel for simd schedule (static, 4) linear(b:2) reduction(+:c)
+  for (i = 0; i < 64; i++)
+    {
+      c = c + (b != 7 + 2 * i);
+      foo (&b, &i, &j, 2);
+    }
+  if (c || i != 64 || b != 7 + 64 * 2)
+    __builtin_abort ();
+  i = 4; j = 4; b = 7;
+  #pragma omp parallel for simd schedule (static, 4) linear(b:3) reduction(+:c)
+  for (i = 0; i < 64; i += 4)
+    {
+      c = c + (b != 7 + i / 4 * 3);
+      foo (&b, &i, &j, 3);
+    }
+  if (c || i != 64 || b != 7 + 16 * 3)
+    __builtin_abort ();
+  i = 4; j = 4; b = 7;
+  #pragma omp parallel for simd schedule (static, 4) linear(i) linear(b:2) 
reduction(+:c)
+  for (i = 0; i < 64; i++)
+    {
+      c = c + (b != 7 + 2 * i);
+      foo (&b, &i, &j, 2);
+    }
+  if (c || i != 64 || b != 7 + 64 * 2)
+    __builtin_abort ();
+  i = 4; j = 4; b = 7;
+  #pragma omp parallel for simd schedule (static, 4) linear(i:4) linear(b:3) 
reduction(+:c)
+  for (i = 0; i < 64; i += 4)
+    {
+      c = c + (b != 7 + i / 4 * 3);
+      foo (&b, &i, &j, 3);
+    }
+  if (c || i != 64 || b != 7 + 16 * 3)
+    __builtin_abort ();
+  i = 4; j = 4; b = 7;
+  #pragma omp parallel for simd lastprivate (i, j) collapse (2) schedule 
(static, 4) linear(b:2) reduction(+:c)
+  for (i = 0; i < 8; i++)
+    for (j = 0; j < 8; j++)
+      {
+       c = c + (b != 7 + 2 * j + 2 * 8 * i);
+       foo (&b, &i, &j, 2);
+      }
+  if (c || i != 8 || j != 8 || b != 7 + 64 * 2)
+    __builtin_abort ();
+  i = 4; j = 4; b = 7;
+  #pragma omp parallel for simd collapse (2) schedule (static, 4) linear(b:2) 
reduction(+:c)
+  for (i = 0; i < 8; i++)
+    for (j = 0; j < 8; j++)
+      {
+       c = c + (b != 7 + 2 * j + 2 * 8 * i);
+       foo (&b, &i, &j, 2);
+      }
+  if (c || i != 8 || j != 8 || b != 7 + 64 * 2)
+    __builtin_abort ();
+  return 0;
+}
--- libgomp/testsuite/libgomp.c/simd-14.c.jj    2014-06-23 15:18:53.217619435 
+0200
+++ libgomp/testsuite/libgomp.c/simd-14.c       2014-06-23 15:17:32.000000000 
+0200
@@ -0,0 +1,123 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+int
+main ()
+{
+  int i, j, b, c = 0;
+  i = 4; j = 4; b = 7;
+  #pragma omp simd linear(b:2) reduction(+:c)
+  for (i = 0; i < 64; i++)
+    {
+      c = c + (b != 7 + 2 * i);
+      b = b + 2;
+    }
+  if (c || i != 64 || b != 7 + 64 * 2)
+    __builtin_abort ();
+  i = 4; j = 4; b = 7;
+  #pragma omp simd linear(b:3) reduction(+:c)
+  for (i = 0; i < 64; i += 4)
+    {
+      c = c + (b != 7 + i / 4 * 3);
+      b = b + 3;
+    }
+  if (c || i != 64 || b != 7 + 16 * 3)
+    __builtin_abort ();
+  i = 4; j = 4; b = 7;
+  #pragma omp simd linear(i) linear(b:2) reduction(+:c)
+  for (i = 0; i < 64; i++)
+    {
+      c = c + (b != 7 + 2 * i);
+      b = b + 2;
+    }
+  if (c || i != 64 || b != 7 + 64 * 2)
+    __builtin_abort ();
+  i = 4; j = 4; b = 7;
+  #pragma omp simd linear(i:4) linear(b:3) reduction(+:c)
+  for (i = 0; i < 64; i += 4)
+    {
+      c = c + (b != 7 + i / 4 * 3);
+      b = b + 3;
+    }
+  if (c || i != 64 || b != 7 + 16 * 3)
+    __builtin_abort ();
+  i = 4; j = 4; b = 7;
+  #pragma omp simd collapse (2) linear(b:2) reduction(+:c)
+  for (i = 0; i < 8; i++)
+    for (j = 0; j < 8; j++)
+      {
+       c = c + (b != 7 + 2 * j + 2 * 8 * i);
+       b = b + 2;
+      }
+  if (c || i != 8 || j != 8 || b != 7 + 64 * 2)
+    __builtin_abort ();
+  i = 4; j = 4; b = 7;
+  #pragma omp simd collapse (2) lastprivate (i, j) linear(b:2) reduction(+:c)
+  for (i = 0; i < 8; i++)
+    for (j = 0; j < 8; j++)
+      {
+       c = c + (b != 7 + 2 * j + 2 * 8 * i);
+       b = b + 2;
+      }
+  if (c || i != 8 || j != 8 || b != 7 + 64 * 2)
+    __builtin_abort ();
+  i = 4; j = 4; b = 7;
+  #pragma omp parallel for simd schedule (static, 4) linear(b:2) reduction(+:c)
+  for (i = 0; i < 64; i++)
+    {
+      c = c + (b != 7 + 2 * i);
+      b = b + 2;
+    }
+  if (c || i != 64 || b != 7 + 64 * 2)
+    __builtin_abort ();
+  i = 4; j = 4; b = 7;
+  #pragma omp parallel for simd schedule (static, 4) linear(b:3) reduction(+:c)
+  for (i = 0; i < 64; i += 4)
+    {
+      c = c + (b != 7 + i / 4 * 3);
+      b = b + 3;
+    }
+  if (c || i != 64 || b != 7 + 16 * 3)
+    __builtin_abort ();
+  i = 4; j = 4; b = 7;
+  #pragma omp parallel for simd schedule (static, 4) linear(i) linear(b:2) 
reduction(+:c)
+  for (i = 0; i < 64; i++)
+    {
+      c = c + (b != 7 + 2 * i);
+      b = b + 2;
+    }
+  if (c || i != 64 || b != 7 + 64 * 2)
+    __builtin_abort ();
+  i = 4; j = 4; b = 7;
+  #pragma omp parallel for simd schedule (static, 4) linear(i:4) linear(b:3) 
reduction(+:c)
+  for (i = 0; i < 64; i += 4)
+    {
+      c = c + (b != 7 + i / 4 * 3);
+      b = b + 3;
+    }
+  if (c || i != 64 || b != 7 + 16 * 3)
+    __builtin_abort ();
+  i = 4; j = 4; b = 7;
+  #pragma omp parallel for simd lastprivate (i, j) collapse (2) schedule 
(static, 4) linear(b:2) reduction(+:c)
+  for (i = 0; i < 8; i++)
+    for (j = 0; j < 8; j++)
+      {
+       c = c + (b != 7 + 2 * j + 2 * 8 * i);
+       b = b + 2;
+      }
+  if (c || i != 8 || j != 8 || b != 7 + 64 * 2)
+    __builtin_abort ();
+  i = 4; j = 4; b = 7;
+  #pragma omp parallel for simd collapse (2) schedule (static, 4) linear(b:2) 
reduction(+:c)
+  for (i = 0; i < 8; i++)
+    for (j = 0; j < 8; j++)
+      {
+       c = c + (b != 7 + 2 * j + 2 * 8 * i);
+       b = b + 2;
+      }
+  if (c || i != 8 || j != 8 || b != 7 + 64 * 2)
+    __builtin_abort ();
+  return 0;
+}
--- libgomp/testsuite/libgomp.c/simd-16.c.jj    2014-06-23 15:51:47.233392215 
+0200
+++ libgomp/testsuite/libgomp.c/simd-16.c       2014-06-23 15:51:30.000000000 
+0200
@@ -0,0 +1,67 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -std=c99" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+int
+main ()
+{
+  int b, c = 0;
+  b = 7;
+  #pragma omp simd linear(b:2) reduction(+:c)
+  for (int i = 0; i < 64; i++)
+    {
+      c = c + (b != 7 + 2 * i);
+      b = b + 2;
+    }
+  if (c || b != 7 + 64 * 2)
+    __builtin_abort ();
+  b = 7;
+  #pragma omp simd linear(b:3) reduction(+:c)
+  for (int i = 0; i < 64; i += 4)
+    {
+      c = c + (b != 7 + i / 4 * 3);
+      b = b + 3;
+    }
+  if (c || b != 7 + 16 * 3)
+    __builtin_abort ();
+  b = 7;
+  #pragma omp simd collapse (2) linear(b:2) reduction(+:c)
+  for (int i = 0; i < 8; i++)
+    for (int j = 0; j < 8; j++)
+      {
+       c = c + (b != 7 + 2 * j + 2 * 8 * i);
+       b = b + 2;
+      }
+  if (c || b != 7 + 64 * 2)
+    __builtin_abort ();
+  b = 7;
+  #pragma omp parallel for simd schedule (static, 4) linear(b:2) reduction(+:c)
+  for (int i = 0; i < 64; i++)
+    {
+      c = c + (b != 7 + 2 * i);
+      b = b + 2;
+    }
+  if (c || b != 7 + 64 * 2)
+    __builtin_abort ();
+  b = 7;
+  #pragma omp parallel for simd schedule (static, 4) linear(b:3) reduction(+:c)
+  for (int i = 0; i < 64; i += 4)
+    {
+      c = c + (b != 7 + i / 4 * 3);
+      b = b + 3;
+    }
+  if (c || b != 7 + 16 * 3)
+    __builtin_abort ();
+  b = 7;
+  #pragma omp parallel for simd collapse (2) schedule (static, 4) linear(b:2) 
reduction(+:c)
+  for (int i = 0; i < 8; i++)
+    for (int j = 0; j < 8; j++)
+      {
+       c = c + (b != 7 + 2 * j + 2 * 8 * i);
+       b = b + 2;
+      }
+  if (c || b != 7 + 64 * 2)
+    __builtin_abort ();
+  return 0;
+}
--- libgomp/testsuite/libgomp.c/for-2.c.jj      2013-10-11 11:23:59.000000000 
+0200
+++ libgomp/testsuite/libgomp.c/for-2.c 2014-06-23 16:47:50.180006296 +0200
@@ -21,11 +21,14 @@ extern void abort (void);
 #undef F
 #undef G
 
+#undef SC
+#define SC static
 #define F for simd
 #define G f_simd
 #include "for-1.h"
 #undef F
 #undef G
+#undef SC
 
 int
 main ()
--- libgomp/testsuite/libgomp.c/for-2.h.jj      2013-10-11 11:23:59.000000000 
+0200
+++ libgomp/testsuite/libgomp.c/for-2.h 2014-06-23 16:39:05.986724903 +0200
@@ -8,6 +8,9 @@ noreturn (void)
   for (;;);
 }
 #endif
+#ifndef SC
+#define SC
+#endif
 
 __attribute__((noinline, noclone)) void
 N(f0) (void)
@@ -57,7 +60,7 @@ __attribute__((noinline, noclone)) void
 N(f5) (int n11, int n12, int n21, int n22, int n31, int n32,
        int s1, int s2, int s3)
 {
-  int v1, v2, v3;
+  SC int v1, v2, v3;
 #pragma omp F S collapse(3)
   for (v1 = n11; v1 < n12; v1 += s1)
     for (v2 = n21; v2 < n22; v2 += s2)
@@ -69,8 +72,8 @@ __attribute__((noinline, noclone)) void
 N(f6) (int n11, int n12, int n21, int n22, long long n31, long long n32,
        int s1, int s2, long long int s3)
 {
-  int v1, v2;
-  long long v3;
+  SC int v1, v2;
+  SC long long v3;
 #pragma omp F S collapse(3)
   for (v1 = n11; v1 > n12; v1 += s1)
     for (v2 = n21; v2 > n22; v2 += s2)
@@ -81,8 +84,8 @@ N(f6) (int n11, int n12, int n21, int n2
 __attribute__((noinline, noclone)) void
 N(f7) (void)
 {
-  unsigned int v1, v3;
-  unsigned long long v2;
+  SC unsigned int v1, v3;
+  SC unsigned long long v2;
 #pragma omp F S collapse(3)
   for (v1 = 0; v1 < 20; v1 += 2)
     for (v2 = __LONG_LONG_MAX__ + 16ULL;
@@ -94,7 +97,7 @@ N(f7) (void)
 __attribute__((noinline, noclone)) void
 N(f8) (void)
 {
-  long long v1, v2, v3;
+  SC long long v1, v2, v3;
 #pragma omp F S collapse(3)
   for (v1 = 0; v1 < 20; v1 += 2)
     for (v2 = 30; v2 < 20; v2++)
@@ -118,7 +121,7 @@ N(f9) (void)
 __attribute__((noinline, noclone)) void
 N(f10) (void)
 {
-  int i;
+  SC int i;
 #pragma omp F S collapse(3)
   for (i = 0; i < 10; i++)
     for (int j = 10; j < 8; j++)
@@ -146,7 +149,7 @@ N(f11) (int n)
 __attribute__((noinline, noclone)) void
 N(f12) (int n)
 {
-  int i;
+  SC int i;
 #pragma omp F S collapse(3)
   for (i = 0; i < 10; i++)
     for (int j = n; j < 8; j++)
@@ -170,7 +173,7 @@ N(f13) (void)
 __attribute__((noinline, noclone)) void
 N(f14) (void)
 {
-  float *i;
+  SC float *i;
 #pragma omp F S collapse(3)
   for (i = &b[0][0][0]; i < &b[0][0][10]; i++)
     for (float *j = &b[0][15][0]; j > &b[0][0][0]; j -= 10)
--- libgomp/testsuite/libgomp.c/simd-17.c.jj    2014-06-23 15:51:53.810359017 
+0200
+++ libgomp/testsuite/libgomp.c/simd-17.c       2014-06-23 16:59:12.413472355 
+0200
@@ -0,0 +1,73 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -std=c99" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+static inline void
+foo (int *b, int *i, int *j, int x)
+{
+  *b = *b + x + (*i - *i) + (*j - *j);
+}
+
+int
+main ()
+{
+  int b, c = 0;
+  b = 7;
+  #pragma omp simd linear(b:2) reduction(+:c)
+  for (int i = 0; i < 64; i++)
+    {
+      c = c + (b != 7 + 2 * i);
+      foo (&b, &i, &i, 2);
+    }
+  if (c || b != 7 + 64 * 2)
+    __builtin_abort ();
+  b = 7;
+  #pragma omp simd linear(b:3) reduction(+:c)
+  for (int i = 0; i < 64; i += 4)
+    {
+      c = c + (b != 7 + i / 4 * 3);
+      foo (&b, &i, &i, 3);
+    }
+  if (c || b != 7 + 16 * 3)
+    __builtin_abort ();
+  b = 7;
+  #pragma omp simd collapse (2) linear(b:2) reduction(+:c)
+  for (int i = 0; i < 8; i++)
+    for (int j = 0; j < 8; j++)
+      {
+       c = c + (b != 7 + 2 * j + 2 * 8 * i);
+       foo (&b, &i, &j, 2);
+      }
+  if (c || b != 7 + 64 * 2)
+    __builtin_abort ();
+  b = 7;
+  #pragma omp parallel for simd schedule (static, 4) linear(b:2) reduction(+:c)
+  for (int i = 0; i < 64; i++)
+    {
+      c = c + (b != 7 + 2 * i);
+      foo (&b, &i, &i, 2);
+    }
+  if (c || b != 7 + 64 * 2)
+    __builtin_abort ();
+  b = 7;
+  #pragma omp parallel for simd schedule (static, 4) linear(b:3) reduction(+:c)
+  for (int i = 0; i < 64; i += 4)
+    {
+      c = c + (b != 7 + i / 4 * 3);
+      foo (&b, &i, &i, 3);
+    }
+  if (c || b != 7 + 16 * 3)
+    __builtin_abort ();
+  b = 7;
+  #pragma omp parallel for simd collapse (2) schedule (static, 4) linear(b:2) 
reduction(+:c)
+  for (int i = 0; i < 8; i++)
+    for (int j = 0; j < 8; j++)
+      {
+       c = c + (b != 7 + 2 * j + 2 * 8 * i);
+       foo (&b, &i, &j, 2);
+      }
+  if (c || b != 7 + 64 * 2)
+    __builtin_abort ();
+  return 0;
+}

        Jakub

Reply via email to