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 OpenMP ICE (PR fortran/69281)


Hi!

On the following testcase we ICE because the BLOCK that is initially in the
BIND_EXPR on the OMP_PARALLEL/TASK/TARGET body contains a VAR_DECL for
-fstack-arrays added artificial VLA.  Later on for move_sese_* reasons this
is the BLOCK used for the moving, which means that a copy of the VAR_DECL
with DECL_VALUE_EXPR is also in the original function where if we version
that function, we might tweak its type and that then turns the *omp_fn*
into invalid IL.  This problem doesn't exist for C/C++, because there we
actually wrap the body into 2 BLOCKs, one user supplied and the other that
just holds the artificials added during gimplification/omp lowering that
aren't problematic.  This patch makes the Fortran FE match the C/C++ more
closely by wrapping the body into another BIND_EXPR with its own BLOCK.

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

2016-08-19  Jakub Jelinek  <jakub@redhat.com>

	PR fortran/69281
	* trans-openmp.c (gfc_trans_omp_parallel, gfc_trans_omp_task,
	gfc_trans_omp_target): Wrap gfc_trans_omp_code result in an extra
	BIND_EXPR with its own forced BLOCK.

	* gfortran.dg/gomp/pr69281.f90: New test.

--- gcc/fortran/trans-openmp.c.jj	2016-07-01 17:11:37.000000000 +0200
+++ gcc/fortran/trans-openmp.c	2016-08-19 14:19:46.246922616 +0200
@@ -3554,7 +3554,9 @@ gfc_trans_omp_parallel (gfc_code *code)
   gfc_start_block (&block);
   omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
 				       code->loc);
+  pushlevel ();
   stmt = gfc_trans_omp_code (code->block->next, true);
+  stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
   stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
 		     omp_clauses);
   gfc_add_expr_to_block (&block, stmt);
@@ -4062,7 +4064,9 @@ gfc_trans_omp_task (gfc_code *code)
   gfc_start_block (&block);
   omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
 				       code->loc);
+  pushlevel ();
   stmt = gfc_trans_omp_code (code->block->next, true);
+  stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
   stmt = build2_loc (input_location, OMP_TASK, void_type_node, stmt,
 		     omp_clauses);
   gfc_add_expr_to_block (&block, stmt);
@@ -4215,7 +4219,11 @@ gfc_trans_omp_target (gfc_code *code)
       = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_TARGET],
 			       code->loc);
   if (code->op == EXEC_OMP_TARGET)
-    stmt = gfc_trans_omp_code (code->block->next, true);
+    {
+      pushlevel ();
+      stmt = gfc_trans_omp_code (code->block->next, true);
+      stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
+    }
   else
     {
       pushlevel ();
--- gcc/testsuite/gfortran.dg/gomp/pr69281.f90.jj	2016-08-19 13:54:11.411692953 +0200
+++ gcc/testsuite/gfortran.dg/gomp/pr69281.f90	2016-08-19 14:23:11.000000000 +0200
@@ -0,0 +1,63 @@
+! PR fortran/69281
+! { dg-do compile }
+! { dg-additional-options "-fstack-arrays -O2" }
+
+program pr69281
+  implicit none
+  call foo1((/ 1, 3, 3, 7 /))
+  call foo2((/ 1, 3, 3, 7 /))
+  call foo3((/ 1, 3, 3, 7 /))
+  call foo4((/ 1, 3, 3, 7 /))
+  call foo5((/ 1, 3, 3, 7 /))
+  call foo6((/ 1, 3, 3, 7 /))
+contains
+  subroutine foo1(x)
+    integer, intent(in) :: x(:)
+    !$omp parallel
+      call baz(bar(x))
+    !$omp end parallel
+  end subroutine
+  subroutine foo2(x)
+    integer, intent(in) :: x(:)
+    !$omp task
+      call baz(bar(x))
+    !$omp end task
+  end subroutine
+  subroutine foo3(x)
+    integer, intent(in) :: x(:)
+    !$omp target
+      call baz(bar(x))
+    !$omp end target
+  end subroutine
+  subroutine foo4(x)
+    integer, intent(in) :: x(:)
+    !$omp target teams
+      call baz(bar(x))
+    !$omp end target teams
+  end subroutine
+  subroutine foo5(x)
+    integer, intent(in) :: x(:)
+    integer :: i
+    !$omp parallel do
+      do i = 1, 1
+        call baz(bar(x))
+      end do
+  end subroutine
+  subroutine foo6(x)
+    integer, intent(in) :: x(:)
+    integer :: i
+    !$omp target teams distribute parallel do
+      do i = 1, 1
+        call baz(bar(x))
+      end do
+  end subroutine
+  function bar(x) result(a)
+    integer, dimension(:), intent(in) :: x
+    integer, dimension(2,size(x)) :: a
+    a(1,:) = 1
+    a(2,:) = x
+  end function
+  subroutine baz(a)
+    integer, dimension(:,:), intent(in) :: a
+  end subroutine
+end program

	Jakub


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