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]

[gomp4] acc routines bugfix


Jim ran into an ICE in a fortran program which contains an acc vector
loop with a call to a subroutine. There are two things going on in here.
First, a couple of functions in tree-nested.c weren't considering the
_GANG, _WORKER, _VECTOR, and _SEQ omp clause codes. Second, the target
lto compiler would fail an assert if a routine clause wasn't applied to
the subroutine.

The second point is interesting. Offloaded functions require the "omp
target" attribute or that function won't reach the lto compiler. That's
fine because not all targets can handle general code. The problem occurs
when a user forgets to bless a function as offloaded, which OpenACC
allows. This patch teaches the lto-wrapper to error on unrecognized
functions with flag_openacc or hit gcc_unreachable otherwise. I couldn't
think of a way to test the lto error message because that involves
having two compilers present. I wonder if it's ok to have libgomp check
for compiler expected compiler errors? However, that's more of a
gcc/testsuite type of check.

I don't think trunk has much support for acc routines just yet, so I
applied this patch to gomp-4_0-branch for now.

Cesar
2015-07-24  Cesar Philippidis  <cesar@codesourcery.com>

	gcc/
	* lto-cgraph.c (input_overwrite_node): Gracefully error on missing
	symbols with flag_openacc.
	* tree-nested.c (convert_nonlocal_omp_clauses): Handle OMP_CLAUSE_GANG,
	OMP_CLAUSE_WORKER, OMP_CLAUSE_VECTOR, and OMP_CLAUSE_SEQ.
	(convert_local_omp_clauses): Likewise.

	libgomp/
	* testsuite/libgomp.oacc-fortran/vector-routine.f90: New test.
	

diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index 97585c9..bc589bd 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -1219,9 +1219,23 @@ input_overwrite_node (struct lto_file_decl_data *file_data,
 				     LDPR_NUM_KNOWN);
   node->instrumentation_clone = bp_unpack_value (bp, 1);
   node->split_part = bp_unpack_value (bp, 1);
-  gcc_assert (flag_ltrans
-	      || (!node->in_other_partition
-		  && !node->used_from_other_partition));
+
+  int success = flag_ltrans || (!node->in_other_partition
+				&& !node->used_from_other_partition);
+
+  if (!success)
+    {
+      if (flag_openacc)
+	{
+	  if (TREE_CODE (node->decl) == FUNCTION_DECL)
+	    error ("Missing routine function %<%s%>", node->name ());
+	  else
+	    error ("Missing declared variable %<%s%>", node->name ());
+	}
+
+      else
+	gcc_unreachable ();
+    }
 }
 
 /* Return string alias is alias of.  */
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index 6b75020..3b02443 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -1188,6 +1188,10 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
 	case OMP_CLAUSE_UNTIED:
 	case OMP_CLAUSE_MERGEABLE:
 	case OMP_CLAUSE_PROC_BIND:
+	case OMP_CLAUSE_GANG:
+	case OMP_CLAUSE_WORKER:
+	case OMP_CLAUSE_VECTOR:
+	case OMP_CLAUSE_SEQ:
 	  break;
 
 	default:
@@ -1828,6 +1832,10 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
 	case OMP_CLAUSE_UNTIED:
 	case OMP_CLAUSE_MERGEABLE:
 	case OMP_CLAUSE_PROC_BIND:
+	case OMP_CLAUSE_GANG:
+	case OMP_CLAUSE_WORKER:
+	case OMP_CLAUSE_VECTOR:
+	case OMP_CLAUSE_SEQ:
 	  break;
 
 	default:
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/vector-routine.f90 b/libgomp/testsuite/libgomp.oacc-fortran/vector-routine.f90
new file mode 100644
index 0000000..a8d078a
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/vector-routine.f90
@@ -0,0 +1,46 @@
+! { dg-do run }
+
+module param
+  integer, parameter :: N = 32
+end module param
+
+program main
+  use param
+  integer :: i
+  integer :: a(N)
+
+  do i = 1, N
+    a(i) = i
+  end do
+
+  !
+  ! Appears there's two bugs...
+  ! 1) loop with vector
+  ! 2) loop without vector
+  !
+
+  !$acc parallel copy (a)
+  !$acc loop vector
+    do i = 1, N
+      call vector (a)
+    end do
+  !$acc end parallel
+
+  do i = 1, N
+    if (a(i) .ne. 0) call abort
+  end do
+
+contains
+
+  subroutine vector (a)
+  !$acc routine vector
+  integer, intent (inout) :: a(N)
+  integer :: i
+
+  do i = 1, N
+    a(i) = a(i) - a(i) 
+  end do
+
+end subroutine vector
+
+end program main

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