PR middle-end/59150
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 26 Nov 2013 20:38:59 +0000 (20:38 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 26 Nov 2013 20:38:59 +0000 (20:38 +0000)
* omp-low.c (lower_rec_input_clause): For reduction with placeholder
of references to constant size types in simd loops, defer emitting
initializer for the new_var, emit it later on only if not using
SIMD arrays for it.

* g++.dg/gomp/pr59150.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@205411 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/omp-low.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/gomp/pr59150.C [new file with mode: 0644]

index b04f539..0d97d2e 100644 (file)
@@ -1,5 +1,11 @@
 2013-11-26  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/59150
+       * omp-low.c (lower_rec_input_clause): For reduction with placeholder
+       of references to constant size types in simd loops, defer emitting
+       initializer for the new_var, emit it later on only if not using
+       SIMD arrays for it.
+
        PR middle-end/59152
        * omp-low.c (expand_omp_for_static_chunk): Don't set loop->latch
        for the inner loop if collapse_bb is non-NULL.
index 7abe456..b980825 100644 (file)
@@ -3185,15 +3185,26 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
                }
              else if (TREE_CONSTANT (x))
                {
-                 const char *name = NULL;
-                 if (DECL_NAME (var))
-                   name = IDENTIFIER_POINTER (DECL_NAME (new_var));
-
-                 x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
-                                         name);
-                 gimple_add_tmp_var (x);
-                 TREE_ADDRESSABLE (x) = 1;
-                 x = build_fold_addr_expr_loc (clause_loc, 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)
+                   x = NULL_TREE;
+                 else
+                   {
+                     const char *name = NULL;
+                     if (DECL_NAME (var))
+                       name = IDENTIFIER_POINTER (DECL_NAME (new_var));
+
+                     x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
+                                             name);
+                     gimple_add_tmp_var (x);
+                     TREE_ADDRESSABLE (x) = 1;
+                     x = build_fold_addr_expr_loc (clause_loc, x);
+                   }
                }
              else
                {
@@ -3201,8 +3212,11 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
                  x = build_call_expr_loc (clause_loc, atmp, 1, x);
                }
 
-             x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
-             gimplify_assign (new_var, x, ilist);
+             if (x)
+               {
+                 x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
+                 gimplify_assign (new_var, x, ilist);
+               }
 
              new_var = build_simple_mem_ref_loc (clause_loc, new_var);
            }
@@ -3500,6 +3514,29 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
                        }
                      break;
                    }
+                 /* If this is a reference to constant size reduction var
+                    with placeholder, we haven't emitted the initializer
+                    for it because it is undesirable if SIMD arrays are used.
+                    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);
+                       }
+                   }
                  x = lang_hooks.decls.omp_clause_default_ctor
                                (c, new_var, unshare_expr (x));
                  if (x)
index 26b50d1..a23c397 100644 (file)
@@ -1,5 +1,8 @@
 2013-11-26  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/59150
+       * g++.dg/gomp/pr59150.C: New test.
+
        PR middle-end/59152
        * c-c++-common/gomp/pr59152.c: New test.
 
diff --git a/gcc/testsuite/g++.dg/gomp/pr59150.C b/gcc/testsuite/g++.dg/gomp/pr59150.C
new file mode 100644 (file)
index 0000000..103edb6
--- /dev/null
@@ -0,0 +1,25 @@
+// PR middle-end/59150
+// { dg-do compile }
+// { dg-options "-O -fopenmp-simd -fno-tree-ccp -fno-tree-copy-prop -fno-tree-dce" }
+
+#pragma omp declare reduction (foo: int: omp_out += omp_in) initializer (omp_priv = 0)
+
+int
+foo ()
+{
+  int i, v, &u = v;
+  #pragma omp simd reduction (foo:u)
+    for (i = 0; i < 1024; i++)
+      u = i;
+  return u;
+}
+
+int
+bar ()
+{
+  int i, v, &u = v;
+  #pragma omp simd reduction (foo:u) safelen(1)
+    for (i = 0; i < 1024; i++)
+      u = i;
+  return u;
+}