]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/61252 (Invalid code produced for omp simd reduction(min:var) where...
authorJakub Jelinek <jakub@redhat.com>
Wed, 21 May 2014 08:04:03 +0000 (10:04 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 21 May 2014 08:04:03 +0000 (10:04 +0200)
PR middle-end/61252
* omp-low.c (handle_simd_reference): New function.
(lower_rec_input_clauses): Use it.  Defer adding reference
initialization even for reduction without placeholder if in simd,
handle it properly later on.

* testsuite/libgomp.c++/simd-9.C: New test.

From-SVN: r210679

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

index fe3e7ec8febd0dfae39a78ee0d7125f3496542b4..f167e76e14007a8aa4c0ad6042f82ec4ebc45c50 100644 (file)
@@ -1,3 +1,11 @@
+2014-05-21  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/61252
+       * omp-low.c (handle_simd_reference): New function.
+       (lower_rec_input_clauses): Use it.  Defer adding reference
+       initialization even for reduction without placeholder if in simd,
+       handle it properly later on.
+
 2014-05-20  Jan Hubicka  <hubicka@ucw.cz>
 
        PR tree-optimization/60899
index a2a64ad1dcd7a047b8b3b2f786acb4f164bbf3e3..95b0e5273d225636304c460a9ee3bca01b31ed46 100644 (file)
@@ -2998,6 +2998,27 @@ lower_rec_simd_input_clauses (tree new_var, omp_context *ctx, int &max_vf,
   return true;
 }
 
+/* Helper function of lower_rec_input_clauses.  For a reference
+   in simd reduction, add an underlying variable it will reference.  */
+
+static void
+handle_simd_reference (location_t loc, tree new_vard, gimple_seq *ilist)
+{
+  tree z = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_vard)));
+  if (TREE_CONSTANT (z))
+    {
+      const char *name = NULL;
+      if (DECL_NAME (new_vard))
+       name = IDENTIFIER_POINTER (DECL_NAME (new_vard));
+
+      z = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_vard)), name);
+      gimple_add_tmp_var (z);
+      TREE_ADDRESSABLE (z) = 1;
+      z = build_fold_addr_expr_loc (loc, z);
+      gimplify_assign (new_vard, z, ilist);
+    }
+}
+
 /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
    from the receiver (aka child) side and initializers for REFERENCE_TYPE
    private variables.  Initialization statements go in ILIST, while calls
@@ -3189,13 +3210,11 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
                }
              else if (TREE_CONSTANT (x))
                {
-                 /* For reduction with placeholder in SIMD loop,
-                    defer adding the initialization of the reference,
-                    because if we decide to use SIMD array for it,
-                    the initilization could cause expansion ICE.  */
-                 if (c_kind == OMP_CLAUSE_REDUCTION
-                     && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
-                     && is_simd)
+                 /* For reduction in SIMD loop, defer adding the
+                    initialization of the reference, because if we decide
+                    to use SIMD array for it, the initilization could cause
+                    expansion ICE.  */
+                 if (c_kind == OMP_CLAUSE_REDUCTION && is_simd)
                    x = NULL_TREE;
                  else
                    {
@@ -3524,23 +3543,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
                     But if they aren't used, we need to emit the deferred
                     initialization now.  */
                  else if (is_reference (var) && is_simd)
-                   {
-                     tree z
-                       = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_vard)));
-                     if (TREE_CONSTANT (z))
-                       {
-                         const char *name = NULL;
-                         if (DECL_NAME (var))
-                           name = IDENTIFIER_POINTER (DECL_NAME (new_vard));
-
-                         z = create_tmp_var_raw
-                               (TREE_TYPE (TREE_TYPE (new_vard)), name);
-                         gimple_add_tmp_var (z);
-                         TREE_ADDRESSABLE (z) = 1;
-                         z = build_fold_addr_expr_loc (clause_loc, z);
-                         gimplify_assign (new_vard, z, ilist);
-                       }
-                   }
+                   handle_simd_reference (clause_loc, new_vard, ilist);
                  x = lang_hooks.decls.omp_clause_default_ctor
                                (c, new_var, unshare_expr (x));
                  if (x)
@@ -3573,6 +3576,13 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
                  if (code == MINUS_EXPR)
                    code = PLUS_EXPR;
 
+                 tree new_vard = new_var;
+                 if (is_simd && is_reference (var))
+                   {
+                     gcc_assert (TREE_CODE (new_var) == MEM_REF);
+                     new_vard = TREE_OPERAND (new_var, 0);
+                     gcc_assert (DECL_P (new_vard));
+                   }
                  if (is_simd
                      && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
                                                       idx, lane, ivar, lvar))
@@ -3584,9 +3594,18 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
                      x = build2 (code, TREE_TYPE (ref), ref, ivar);
                      ref = build_outer_var_ref (var, ctx);
                      gimplify_assign (ref, x, &llist[1]);
+
+                     if (new_vard != new_var)
+                       {
+                         SET_DECL_VALUE_EXPR (new_vard,
+                                              build_fold_addr_expr (lvar));
+                         DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
+                       }
                    }
                  else
                    {
+                     if (is_reference (var) && is_simd)
+                       handle_simd_reference (clause_loc, new_vard, ilist);
                      gimplify_assign (new_var, x, ilist);
                      if (is_simd)
                        {
index 9e02f5426e53ba9c886c6c4665cf3075c667cefe..45daf0e6597c65200800ba33182cdbede88ff9dd 100644 (file)
@@ -1,3 +1,8 @@
+2014-05-21  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/61252
+       * testsuite/libgomp.c++/simd-9.C: New test.
+
 2014-05-18  Uros Bizjak  <ubizjak@gmail.com>
 
        * libgomp.texi (Runitme Library Routines): Remove multiple @menu.
diff --git a/libgomp/testsuite/libgomp.c++/simd-9.C b/libgomp/testsuite/libgomp.c++/simd-9.C
new file mode 100644 (file)
index 0000000..3c567b3
--- /dev/null
@@ -0,0 +1,52 @@
+// { dg-do run }
+// { dg-options "-O2" }
+// { dg-additional-options "-msse2" { target sse2_runtime } }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+
+extern "C" void abort ();
+int a[1024] __attribute__((aligned (32))) = { 1 };
+#pragma omp declare reduction (foo:int:omp_out += omp_in) \
+                   initializer (omp_priv = 0)
+
+__attribute__((noinline, noclone)) void
+foo (int &u, int &v)
+{
+  int i;
+  #pragma omp simd aligned(a : 32) reduction(foo:u) reduction(+:v)
+  for (i = 0; i < 1024; i++)
+    {
+      int x = a[i];
+      u += x;
+      v += x;
+    }
+}
+
+__attribute__((noinline, noclone)) void
+bar (int &u, int &v)
+{
+  int i;
+  #pragma omp simd aligned(a : 32) reduction(foo:u) reduction(+:v) \
+                  safelen(1)
+  for (i = 0; i < 1024; i++)
+    {
+      int x = a[i];
+      u += x;
+      v += x;
+    }
+}
+
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 1024; i++)
+    a[i] = (i & 31) + (i / 128);
+  int u = 0, v = 0;
+  foo (u, v);
+  if (u != 19456 || v != 19456)
+    abort ();
+  u = 0; v = 0;
+  bar (u, v);
+  if (u != 19456 || v != 19456)
+    abort ();
+}