diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 865fb6adcea2..cee2e438b583 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
 2006-05-16  Jakub Jelinek  <jakub@redhat.com>
 
+	PR middle-end/27573
+	* omp-low.c (expand_omp_parallel): Don't assert
+	.OMP_DATA_I = &.OMP_DATA_O is the first statement in the block,
+	instead search for it.
+
 	PR c/27499
 	* gimplify.c (gimplify_omp_for): Remove assertion that iteration var
 	is signed.
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 2b691fa4c4d1..c1441dc44587 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -2456,7 +2456,8 @@ expand_omp_parallel (struct omp_region *region)
   else
     {
       /* If the parallel region needs data sent from the parent
-	 function, then the very first statement of the parallel body
+	 function, then the very first statement (except possible
+	 tree profile counter updates) of the parallel body
 	 is a copy assignment .OMP_DATA_I = &.OMP_DATA_O.  Since
 	 &.OMP_DATA_O is passed as an argument to the child function,
 	 we need to replace it with the argument as seen by the child
@@ -2470,21 +2471,26 @@ expand_omp_parallel (struct omp_region *region)
       if (OMP_PARALLEL_DATA_ARG (entry_stmt))
 	{
 	  basic_block entry_succ_bb = single_succ (entry_bb);
-	  block_stmt_iterator si = bsi_start (entry_succ_bb);
-	  tree stmt;
+	  block_stmt_iterator si;
 
-	  gcc_assert (!bsi_end_p (si));
+	  for (si = bsi_start (entry_succ_bb); ; bsi_next (&si))
+	    {
+	      tree stmt;
 
-	  stmt = bsi_stmt (si);
-	  gcc_assert (TREE_CODE (stmt) == MODIFY_EXPR
-		      && TREE_CODE (TREE_OPERAND (stmt, 1)) == ADDR_EXPR
-		      && TREE_OPERAND (TREE_OPERAND (stmt, 1), 0)
-			 == OMP_PARALLEL_DATA_ARG (entry_stmt));
-
-	  if (TREE_OPERAND (stmt, 0) == DECL_ARGUMENTS (child_fn))
-	    bsi_remove (&si, true);
-	  else
-	    TREE_OPERAND (stmt, 1) = DECL_ARGUMENTS (child_fn);
+	      gcc_assert (!bsi_end_p (si));
+	      stmt = bsi_stmt (si);
+	      if (TREE_CODE (stmt) == MODIFY_EXPR
+		  && TREE_CODE (TREE_OPERAND (stmt, 1)) == ADDR_EXPR
+		  && TREE_OPERAND (TREE_OPERAND (stmt, 1), 0)
+		     == OMP_PARALLEL_DATA_ARG (entry_stmt))
+		{
+		  if (TREE_OPERAND (stmt, 0) == DECL_ARGUMENTS (child_fn))
+		    bsi_remove (&si, true);
+		  else
+		    TREE_OPERAND (stmt, 1) = DECL_ARGUMENTS (child_fn);
+		  break;
+		}
+	    }
 	}
 
       /* Declare local variables needed in CHILD_CFUN.  */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e9f17325dce8..8e94d149213a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
 2006-05-16  Jakub Jelinek  <jakub@redhat.com>
 
+	PR middle-end/27573
+	* gcc.dg/gomp/pr27573.c: New test.
+	* gfortran.dg/gomp/pr27573.f90: New test.
+
 	PR c/27499
 	* gcc.dg/gomp/pr27499.c: New test.
 	* g++.dg/gomp/pr27499.C: New test.
diff --git a/gcc/testsuite/gcc.dg/gomp/pr27573.c b/gcc/testsuite/gcc.dg/gomp/pr27573.c
new file mode 100644
index 000000000000..4dca4da43c66
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/pr27573.c
@@ -0,0 +1,20 @@
+/* PR middle-end/27573 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fopenmp -fprofile-generate" } */
+
+extern int puts (const char *);
+
+int
+main (void)
+{
+  int i, j = 8;
+#pragma omp parallel
+  {
+    puts ("foo");
+    for (i = 1; i < j - 1; i++)
+      ;
+  }
+  return 0;
+}
+
+/* { dg-final { cleanup-coverage-files } } */
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr27573.f90 b/gcc/testsuite/gfortran.dg/gomp/pr27573.f90
new file mode 100644
index 000000000000..9d20284044be
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/pr27573.f90
@@ -0,0 +1,15 @@
+! PR middle-end/27573
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fprofile-generate" }
+
+program pr27573
+  integer i,j
+  j = 8
+  !$omp parallel
+    print *, "foo"
+    do i = 1, j - 1
+    end do
+  !$omp end parallel
+end
+
+! { dg-final { cleanup-coverage-files } }