re PR middle-end/66702 (#pragma omp declare simd uniform and linear issues)
authorJakub Jelinek <jakub@redhat.com>
Tue, 30 Jun 2015 12:12:42 +0000 (14:12 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 30 Jun 2015 12:12:42 +0000 (14:12 +0200)
PR middle-end/66702
* omp-low.c (simd_clone_adjust): Handle addressable linear
or uniform parameters or non-gimple type uniform parameters.

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

From-SVN: r225179

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

index 6f919643f37a9b678cf20d985ebae5e3121643a6..4d11ef546ccd353426910705dca01b512677dfb2 100644 (file)
@@ -1,3 +1,9 @@
+2015-06-30  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/66702
+       * omp-low.c (simd_clone_adjust): Handle addressable linear
+       or uniform parameters or non-gimple type uniform parameters.
+
 2015-06-30  Richard Biener  <rguenther@suse.de>
 
        * fold-const.c (fold_unary_loc): Move abs(abs(x)) -> abs(x),
index 8218403f6803c32ea63da5c4558c920f6c313b26..2e2070a739756ef8790232e5f0eb2f3480cf8eef 100644 (file)
@@ -13425,12 +13425,54 @@ simd_clone_adjust (struct cgraph_node *node)
      uniform args with __builtin_assume_aligned (arg_N(D), alignment)
      lhs.  Handle linear by adding PHIs.  */
   for (unsigned i = 0; i < node->simdclone->nargs; i++)
-    if (node->simdclone->args[i].alignment
-       && node->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM
-       && (node->simdclone->args[i].alignment
-           & (node->simdclone->args[i].alignment - 1)) == 0
-       && TREE_CODE (TREE_TYPE (node->simdclone->args[i].orig_arg))
-          == POINTER_TYPE)
+    if (node->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM
+       && (TREE_ADDRESSABLE (node->simdclone->args[i].orig_arg)
+           || !is_gimple_reg_type
+                       (TREE_TYPE (node->simdclone->args[i].orig_arg))))
+      {
+       tree orig_arg = node->simdclone->args[i].orig_arg;
+       if (is_gimple_reg_type (TREE_TYPE (orig_arg)))
+         iter1 = make_ssa_name (TREE_TYPE (orig_arg));
+       else
+         {
+           iter1 = create_tmp_var_raw (TREE_TYPE (orig_arg));
+           gimple_add_tmp_var (iter1);
+         }
+       gsi = gsi_after_labels (entry_bb);
+       g = gimple_build_assign (iter1, orig_arg);
+       gsi_insert_before (&gsi, g, GSI_NEW_STMT);
+       gsi = gsi_after_labels (body_bb);
+       g = gimple_build_assign (orig_arg, iter1);
+       gsi_insert_before (&gsi, g, GSI_NEW_STMT);
+      }
+    else if (node->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM
+            && DECL_BY_REFERENCE (node->simdclone->args[i].orig_arg)
+            && TREE_CODE (TREE_TYPE (node->simdclone->args[i].orig_arg))
+               == REFERENCE_TYPE
+            && TREE_ADDRESSABLE
+                 (TREE_TYPE (TREE_TYPE (node->simdclone->args[i].orig_arg))))
+      {
+       tree orig_arg = node->simdclone->args[i].orig_arg;
+       tree def = ssa_default_def (cfun, orig_arg);
+       if (def && !has_zero_uses (def))
+         {
+           iter1 = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (orig_arg)));
+           gimple_add_tmp_var (iter1);
+           gsi = gsi_after_labels (entry_bb);
+           g = gimple_build_assign (iter1, build_simple_mem_ref (def));
+           gsi_insert_before (&gsi, g, GSI_NEW_STMT);
+           gsi = gsi_after_labels (body_bb);
+           g = gimple_build_assign (build_simple_mem_ref (def), iter1);
+           gsi_insert_before (&gsi, g, GSI_NEW_STMT);
+         }
+      }
+    else if (node->simdclone->args[i].alignment
+            && node->simdclone->args[i].arg_type
+               == SIMD_CLONE_ARG_TYPE_UNIFORM
+            && (node->simdclone->args[i].alignment
+                & (node->simdclone->args[i].alignment - 1)) == 0
+            && TREE_CODE (TREE_TYPE (node->simdclone->args[i].orig_arg))
+               == POINTER_TYPE)
       {
        unsigned int alignment = node->simdclone->args[i].alignment;
        tree orig_arg = node->simdclone->args[i].orig_arg;
@@ -13480,13 +13522,31 @@ simd_clone_adjust (struct cgraph_node *node)
             == SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP)
       {
        tree orig_arg = node->simdclone->args[i].orig_arg;
-       tree def = ssa_default_def (cfun, orig_arg);
        gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (orig_arg))
                    || POINTER_TYPE_P (TREE_TYPE (orig_arg)));
-       if (def && !has_zero_uses (def))
+       tree def = NULL_TREE;
+       if (TREE_ADDRESSABLE (orig_arg))
+         {
+           def = make_ssa_name (TREE_TYPE (orig_arg));
+           iter1 = make_ssa_name (TREE_TYPE (orig_arg));
+           iter2 = make_ssa_name (TREE_TYPE (orig_arg));
+           gsi = gsi_after_labels (entry_bb);
+           g = gimple_build_assign (def, orig_arg);
+           gsi_insert_before (&gsi, g, GSI_NEW_STMT);
+         }
+       else
+         {
+           def = ssa_default_def (cfun, orig_arg);
+           if (!def || has_zero_uses (def))
+             def = NULL_TREE;
+           else
+             {
+               iter1 = make_ssa_name (orig_arg);
+               iter2 = make_ssa_name (orig_arg);
+             }
+         }
+       if (def)
          {
-           iter1 = make_ssa_name (orig_arg);
-           iter2 = make_ssa_name (orig_arg);
            phi = create_phi_node (iter1, body_bb);
            add_phi_arg (phi, def, preheader_edge, UNKNOWN_LOCATION);
            add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION);
@@ -13503,12 +13563,19 @@ simd_clone_adjust (struct cgraph_node *node)
            imm_use_iterator iter;
            use_operand_p use_p;
            gimple use_stmt;
-           FOR_EACH_IMM_USE_STMT (use_stmt, iter, def)
-             if (use_stmt == phi)
-               continue;
-             else
-               FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
-                 SET_USE (use_p, iter1);
+           if (TREE_ADDRESSABLE (orig_arg))
+             {
+               gsi = gsi_after_labels (body_bb);
+               g = gimple_build_assign (orig_arg, iter1);
+               gsi_insert_before (&gsi, g, GSI_NEW_STMT);
+             }
+           else
+             FOR_EACH_IMM_USE_STMT (use_stmt, iter, def)
+               if (use_stmt == phi)
+                 continue;
+               else
+                 FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
+                   SET_USE (use_p, iter1);
          }
       }
 
index a5c51f5639d2e071bbe6a89023c2fb9eb3c5c21b..2f1346de106f2b28926715090271107037a7bce5 100644 (file)
@@ -1,3 +1,9 @@
+2015-06-30  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/66702
+       * testsuite/libgomp.c++/pr66702-1.C: New test.
+       * testsuite/libgomp.c++/pr66702-2.C: New test.
+
 2015-06-30  Tom de Vries  <tom@codesourcery.com>
 
        * testsuite/libgomp.c/parloops-exit-first-loop-alt-5.c: New test.
diff --git a/libgomp/testsuite/libgomp.c++/pr66702-1.C b/libgomp/testsuite/libgomp.c++/pr66702-1.C
new file mode 100644 (file)
index 0000000..1577256
--- /dev/null
@@ -0,0 +1,49 @@
+// PR middle-end/66702
+// { dg-options "-O2" }
+// { dg-additional-options "-msse2" { target sse2_runtime } }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+
+void
+bar (int &a, int &b, int *&c, int &d)
+{
+  volatile int x;
+  int *volatile y;
+  x = a; a = x;
+  x = b; b = x;
+  y = c; c = y;
+  x = d; d = x;
+}
+
+void (*volatile barp) (int &, int &, int *&, int &) = bar;
+
+#pragma omp declare simd uniform(b, c) linear(d:2) aligned(c:32) notinbranch
+int
+foo (int a, int b, int *c, int d)
+{
+  a++;
+  b++;
+  c += 8;
+  d += 2;
+  barp (a, b, c, d);
+  return a + b + *c + d;
+}
+
+volatile int e = 5;
+int c[64] __attribute__((aligned (32)));
+
+int
+main ()
+{
+  int d = 7, r = 0;
+  int b = e;
+  for (int i = 0; i < 64; i++)
+    c[i] = i;
+  #pragma omp simd reduction(+:r) linear(d:2)
+  for (int i = 0; i < 64; i++)
+    {
+      r += foo (i, b, c, d);
+      d += 2;
+    }
+  if (r != 7584)
+    __builtin_abort ();
+}
diff --git a/libgomp/testsuite/libgomp.c++/pr66702-2.C b/libgomp/testsuite/libgomp.c++/pr66702-2.C
new file mode 100644 (file)
index 0000000..7de3de0
--- /dev/null
@@ -0,0 +1,34 @@
+// PR middle-end/66702
+// { dg-options "-O2" }
+// { dg-additional-options "-msse2" { target sse2_runtime } }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+
+struct S { int s1, s2; };
+struct T { T (); ~T (); int t; };
+
+T::T () : t(0) {}
+T::~T () {}
+
+#pragma omp declare simd uniform(b, c) notinbranch
+__attribute__((noinline)) int
+foo (int a, S b, T c)
+{
+  a++;
+  b.s1++;
+  b.s2++;
+  c.t++;
+  return a + b.s1 + b.s2 + c.t;
+}
+
+int
+main ()
+{
+  int r = 0;
+  S s = { 2, 3 };
+  T t;
+  #pragma omp simd reduction(+:r)
+  for (int i = 0; i < 64; i++)
+    r += foo (i, s, t);
+  if (r != 2592)
+    __builtin_abort ();
+}