[committed] Fix up __builtin_adjust_template handling in omp parallel/task code (PR middle-end/52547)

Jakub Jelinek jakub@redhat.com
Thu Mar 22 19:35:00 GMT 2012


Hi!

This patch fixes ICE when a nested function is called from within
#pragma omp {parallel,task} region.  We need to put the temporaries
inside of the parallel/task region body, instead of the function body,
as nothing is adding private clauses for them.

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

The usual gotchas of mixing nested functions and OpenMP remain, the
nested functions don't access the privatized copies of variables if any,
so it works as expected only when the nested function accesses shared
variables only.  And non-local goto from the nested functions doesn't
work for various reasons, even fixing just the cfg verification failures
(with cfun->has_nonlocal_label GOMP_parallel_start etc. are all bb enders)
it accesses undefined labels, etc.

2012-03-22  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/52547
	* tree-nested.c (convert_tramp_reference_stmt): Call declare_vars
	on any new_local_var_chain vars declared during recursing on
	GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK body.

	* testsuite/libgomp.c/pr52547.c: New test.

--- gcc/tree-nested.c.jj	2011-10-12 20:28:20.000000000 +0200
+++ gcc/tree-nested.c	2012-03-22 13:56:53.704506716 +0100
@@ -1954,6 +1954,7 @@ static tree
 convert_tramp_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
 			      struct walk_stmt_info *wi)
 {
+  struct nesting_info *info = (struct nesting_info *) wi->info;
   gimple stmt = gsi_stmt (*gsi);
 
   switch (gimple_code (stmt))
@@ -1966,16 +1967,33 @@ convert_tramp_reference_stmt (gimple_stm
 	for (i = 0; i < nargs; i++)
 	  walk_tree (gimple_call_arg_ptr (stmt, i), convert_tramp_reference_op,
 		     wi, NULL);
+	break;
+      }
 
-	*handled_ops_p = true;
-	return NULL_TREE;
+    case GIMPLE_OMP_PARALLEL:
+    case GIMPLE_OMP_TASK:
+      {
+	tree save_local_var_chain;
+        walk_gimple_op (stmt, convert_tramp_reference_op, wi);
+	save_local_var_chain = info->new_local_var_chain;
+	info->new_local_var_chain = NULL;
+        walk_body (convert_tramp_reference_stmt, convert_tramp_reference_op,
+		   info, gimple_omp_body (stmt));
+	if (info->new_local_var_chain)
+	  declare_vars (info->new_local_var_chain,
+			gimple_seq_first_stmt (gimple_omp_body (stmt)),
+			false);
+	info->new_local_var_chain = save_local_var_chain;
       }
+      break;
 
     default:
+      *handled_ops_p = false;
+      return NULL_TREE;
       break;
     }
 
-  *handled_ops_p = false;
+  *handled_ops_p = true;
   return NULL_TREE;
 }
 
--- libgomp/testsuite/libgomp.c/pr52547.c.jj	2012-03-22 15:45:15.836421355 +0100
+++ libgomp/testsuite/libgomp.c/pr52547.c	2012-03-22 15:43:17.000000000 +0100
@@ -0,0 +1,36 @@
+/* PR middle-end/52547 */
+/* { dg-do run } */
+
+extern void abort (void);
+
+__attribute__((noinline, noclone)) int
+baz (int *x, int (*fn) (int *))
+{
+  return fn (x);
+}
+
+__attribute__((noinline, noclone)) int
+foo (int x, int *y)
+{
+  int i, e = 0;
+#pragma omp parallel for reduction(|:e)
+  for (i = 0; i < x; ++i)
+    {
+      __label__ lab;
+      int bar (int *z) { return z - y; }
+      if (baz (&y[i], bar) != i)
+	e |= 1;
+    }
+  return e;
+}
+
+int
+main ()
+{
+  int a[100], i;
+  for (i = 0; i < 100; i++)
+    a[i] = i;
+  if (foo (100, a))
+    abort ();
+  return 0;
+}

	Jakub



More information about the Gcc-patches mailing list