This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[committed] Fix simd reference reductions (PR middle-end/59150)


Hi!

The problem here is that lower_rec_input_clauses for privatized reference
vars in clauses adds u = &u.1; statements, which is usually the right thing,
but if this is a reduction in simd loop for which we are going to handle
using simd arrays, then we want to set DECL_VALUE_EXPR of the var to
something and having statement referencing such value in the IL is
undesirable.  Normally it will be removed as dead before expansion,
but with a few disabled optimizations it can make it through to expansion
and ICE there.

Fixed by deferring addition of the u = &u.1; statement for references
with reductions with placeholders.

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

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.

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

--- gcc/omp-low.c.jj	2013-11-26 14:20:46.000000000 +0100
+++ gcc/omp-low.c	2013-11-26 15:59:28.478863002 +0100
@@ -3185,15 +3185,26 @@ lower_rec_input_clauses (tree clauses, g
 		}
 	      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, g
 		  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, g
 			}
 		      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)
--- gcc/testsuite/g++.dg/gomp/pr59150.C.jj	2013-11-26 16:02:00.452084567 +0100
+++ gcc/testsuite/g++.dg/gomp/pr59150.C	2013-11-26 16:01:41.000000000 +0100
@@ -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;
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]