public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PR fortran/72741] Handle intrinsic functions specified in !$ACC ROUTINE ( NAME )
@ 2016-08-12 16:16   ` Thomas Schwinge
  2019-02-28 20:37     ` [PR72741, PR89433] Accept intrinsic symbols in Fortran OpenACC 'routine' directives Thomas Schwinge
  0 siblings, 1 reply; 4+ messages in thread
From: Thomas Schwinge @ 2016-08-12 16:16 UTC (permalink / raw)
  To: gcc-patches, fortran; +Cc: Cesar Philippidis, Tobias Burnus, Jakub Jelinek

Hi!

Let me actually break this out of the other pending patches; this should
be uncontroversial.  Originally by Cesar, extended by me.  OK for trunk?

commit a0fee96c0f204814e87ddf6635f9cbec2afc6887
Author: Thomas Schwinge <thomas@codesourcery.com>
Date:   Fri Aug 12 17:19:05 2016 +0200

    [PR fortran/72741] Handle intrinsic functions specified in !$ACC ROUTINE ( NAME )
    
    	gcc/fortran/
    	* openmp.c (gfc_match_oacc_routine): Handle intrinsic functions.
    	gcc/testsuite/
    	* gfortran.dg/goacc/pr72741-intrinsic-1.f: New file.
    	* gfortran.dg/goacc/pr72741-intrinsic-2.f: Likewise.
---
 gcc/fortran/openmp.c                               |   26 ++++++++++++++++----
 .../gfortran.dg/goacc/pr72741-intrinsic-1.f        |   20 +++++++++++++++
 .../gfortran.dg/goacc/pr72741-intrinsic-2.f        |   22 +++++++++++++++++
 3 files changed, 63 insertions(+), 5 deletions(-)

diff --git gcc/fortran/openmp.c gcc/fortran/openmp.c
index 9fff994..dc8197e 100644
--- gcc/fortran/openmp.c
+++ gcc/fortran/openmp.c
@@ -1748,8 +1748,9 @@ match
 gfc_match_oacc_routine (void)
 {
   locus old_loc;
+  match m;
+  gfc_intrinsic_sym *isym = NULL;
   gfc_symbol *sym = NULL;
-  match m;
   gfc_omp_clauses *c = NULL;
   gfc_oacc_routine_name *n = NULL;
 
@@ -1769,12 +1770,14 @@ gfc_match_oacc_routine (void)
   if (m == MATCH_YES)
     {
       char buffer[GFC_MAX_SYMBOL_LEN + 1];
-      gfc_symtree *st;
+      gfc_symtree *st = NULL;
 
       m = gfc_match_name (buffer);
       if (m == MATCH_YES)
 	{
-	  st = gfc_find_symtree (gfc_current_ns->sym_root, buffer);
+	  if ((isym = gfc_find_function (buffer)) == NULL
+	      && (isym = gfc_find_subroutine (buffer)) == NULL)
+	    st = gfc_find_symtree (gfc_current_ns->sym_root, buffer);
 	  if (st)
 	    {
 	      sym = st->n.sym;
@@ -1782,7 +1785,7 @@ gfc_match_oacc_routine (void)
 	        sym = NULL;
 	    }
 
-	  if (st == NULL
+	  if ((isym == NULL && st == NULL)
 	      || (sym
 		  && !sym->attr.external
 		  && !sym->attr.function
@@ -1816,7 +1819,18 @@ gfc_match_oacc_routine (void)
 	  != MATCH_YES))
     return MATCH_ERROR;
 
-  if (sym != NULL)
+  if (isym != NULL)
+    {
+      if (c && (c->gang || c->worker || c->vector))
+	{
+	  gfc_error ("Intrinsic function specified in !$ACC ROUTINE ( NAME )"
+		     " at %C, with incompatible GANG, WORKER, or VECTOR clause");
+	  goto cleanup;
+	}
+      /* The intrinsic symbol has been marked with a SEQ, or with no clause at
+	 all, which is OK.  */
+    }
+  else if (sym != NULL)
     {
       n = gfc_get_oacc_routine_name ();
       n->sym = sym;
@@ -1836,6 +1850,8 @@ gfc_match_oacc_routine (void)
       gfc_current_ns->proc_name->attr.oacc_function
 	= gfc_oacc_routine_dims (c) + 1;
     }
+  else
+    gcc_unreachable ();
 
   if (n)
     n->clauses = c;
diff --git gcc/testsuite/gfortran.dg/goacc/pr72741-intrinsic-1.f gcc/testsuite/gfortran.dg/goacc/pr72741-intrinsic-1.f
new file mode 100644
index 0000000..4bff3e3
--- /dev/null
+++ gcc/testsuite/gfortran.dg/goacc/pr72741-intrinsic-1.f
@@ -0,0 +1,20 @@
+! Check for valid clauses with intrinsic function specified in !$ACC ROUTINE ( NAME ).
+
+      SUBROUTINE sub_1
+      IMPLICIT NONE
+!$ACC ROUTINE (ABORT)
+!$ACC ROUTINE (ABORT) SEQ
+
+      CALL ABORT
+      END SUBROUTINE sub_1
+
+      MODULE m_w_1
+      IMPLICIT NONE
+!$ACC ROUTINE (ABORT) SEQ
+!$ACC ROUTINE (ABORT)
+
+      CONTAINS
+      SUBROUTINE sub_2
+      CALL ABORT
+      END SUBROUTINE sub_2
+      END MODULE m_w_1
diff --git gcc/testsuite/gfortran.dg/goacc/pr72741-intrinsic-2.f gcc/testsuite/gfortran.dg/goacc/pr72741-intrinsic-2.f
new file mode 100644
index 0000000..fed8e76
--- /dev/null
+++ gcc/testsuite/gfortran.dg/goacc/pr72741-intrinsic-2.f
@@ -0,0 +1,22 @@
+! Check for invalid clauses with intrinsic function specified in !$ACC ROUTINE ( NAME ).
+
+      SUBROUTINE sub_1
+      IMPLICIT NONE
+!$ACC ROUTINE (ABORT) WORKER ! { dg-error "Intrinsic function specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\), with incompatible GANG, WORKER, or VECTOR clause" }
+!$ACC ROUTINE (ABORT) GANG ! { dg-error "Intrinsic function specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\), with incompatible GANG, WORKER, or VECTOR clause" }
+!$ACC ROUTINE (ABORT) VECTOR ! { dg-error "Intrinsic function specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\), with incompatible GANG, WORKER, or VECTOR clause" }
+
+      CALL ABORT
+      END SUBROUTINE sub_1
+
+      MODULE m_w_1
+      IMPLICIT NONE
+!$ACC ROUTINE (ABORT) VECTOR ! { dg-error "Intrinsic function specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\), with incompatible GANG, WORKER, or VECTOR clause" }
+!$ACC ROUTINE (ABORT) WORKER ! { dg-error "Intrinsic function specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\), with incompatible GANG, WORKER, or VECTOR clause" }
+!$ACC ROUTINE (ABORT) GANG ! { dg-error "Intrinsic function specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\), with incompatible GANG, WORKER, or VECTOR clause" }
+
+      CONTAINS
+      SUBROUTINE sub_2
+      CALL ABORT
+      END SUBROUTINE sub_2
+      END MODULE m_w_1


Already committed to gomp-4_0-branch in r239422:

commit 490d6fe982666a873ed30d1b2a011090980324e4
Author: tschwinge <tschwinge@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Fri Aug 12 16:12:33 2016 +0000

    [PR fortran/72741] Check clauses with intrinsic function specified in !$ACC ROUTINE ( NAME )
    
    	gcc/fortran/
    	* openmp.c (gfc_match_oacc_routine): Check clauses of intrinsic
    	functions.
    	gcc/testsuite/
    	* gfortran.dg/goacc/pr72741-intrinsic-1.f: New file.
    	* gfortran.dg/goacc/pr72741-intrinsic-2.f: Likewise.
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gomp-4_0-branch@239422 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/fortran/ChangeLog.gomp                         |    7 ++++++
 gcc/fortran/openmp.c                               |   25 +++++++++++++-------
 gcc/testsuite/ChangeLog.gomp                       |    7 ++++++
 .../gfortran.dg/goacc/pr72741-intrinsic-1.f        |   20 ++++++++++++++++
 .../gfortran.dg/goacc/pr72741-intrinsic-2.f        |   22 +++++++++++++++++
 5 files changed, 73 insertions(+), 8 deletions(-)

diff --git gcc/fortran/ChangeLog.gomp gcc/fortran/ChangeLog.gomp
index 8744607..8b4ffc9 100644
--- gcc/fortran/ChangeLog.gomp
+++ gcc/fortran/ChangeLog.gomp
@@ -1,3 +1,10 @@
+2016-08-12  Cesar Philippidis  <cesar@codesourcery.com>
+	    Thomas Schwinge  <thomas@codesourcery.com>
+
+	PR fortran/72741
+	* openmp.c (gfc_match_oacc_routine): Check clauses of intrinsic
+	functions.
+
 2016-07-29  Chung-Lin Tang  <cltang@codesourcery.com>
 
 	PR fortran/70598
diff --git gcc/fortran/openmp.c gcc/fortran/openmp.c
index e463df7..80f46c0 100644
--- gcc/fortran/openmp.c
+++ gcc/fortran/openmp.c
@@ -1919,11 +1919,11 @@ match
 gfc_match_oacc_routine (void)
 {
   locus old_loc;
+  match m;
+  gfc_intrinsic_sym *isym = NULL;
   gfc_symbol *sym = NULL;
-  match m;
   gfc_omp_clauses *c = NULL;
   gfc_oacc_routine_name *n = NULL;
-  gfc_intrinsic_sym *isym = NULL;
   oacc_function dims = OACC_FUNCTION_NONE;
 
   old_loc = gfc_current_locus;
@@ -1957,7 +1957,7 @@ gfc_match_oacc_routine (void)
 	        sym = NULL;
 	    }
 
-	  if ((st == NULL && isym == NULL)
+	  if ((isym == NULL && st == NULL)
 	      || (sym
 		  && !sym->attr.external
 		  && !sym->attr.function
@@ -1996,14 +1996,21 @@ gfc_match_oacc_routine (void)
   dims = gfc_oacc_routine_dims (c);
   if (dims == OACC_FUNCTION_NONE)
     {
-      gfc_error ("Multiple loop axes specified for routine %C");
-      gfc_current_locus = old_loc;
-      return MATCH_ERROR;
+      gfc_error ("Multiple loop axes specified in !$ACC ROUTINE at %C");
+      goto cleanup;
     }
 
   if (isym != NULL)
-    /* There is nothing to do for intrinsic procedures.  */
-    ;
+    {
+      if (c && (c->gang || c->worker || c->vector))
+	{
+	  gfc_error ("Intrinsic function specified in !$ACC ROUTINE ( NAME )"
+		     " at %C, with incompatible GANG, WORKER, or VECTOR clause");
+	  goto cleanup;
+	}
+      /* The intrinsic symbol has been marked with a SEQ, or with no clause at
+	 all, which is OK.  */
+    }
   else if (sym != NULL)
     {
       n = gfc_get_oacc_routine_name ();
@@ -2025,6 +2032,8 @@ gfc_match_oacc_routine (void)
       gfc_current_ns->proc_name->attr.oacc_function_nohost
 	= c ? c->nohost : false;
     }
+  else
+    gcc_unreachable ();
 
   if (n)
     n->clauses = c;
diff --git gcc/testsuite/ChangeLog.gomp gcc/testsuite/ChangeLog.gomp
index 0b96504..8de44b6 100644
--- gcc/testsuite/ChangeLog.gomp
+++ gcc/testsuite/ChangeLog.gomp
@@ -1,3 +1,10 @@
+2016-08-12  Cesar Philippidis  <cesar@codesourcery.com>
+	    Thomas Schwinge  <thomas@codesourcery.com>
+
+	PR fortran/72741
+	* gfortran.dg/goacc/pr72741-intrinsic-1.f: New file.
+	* gfortran.dg/goacc/pr72741-intrinsic-2.f: Likewise.
+
 2016-08-04  Thomas Schwinge  <thomas@codesourcery.com>
 
 	* g++.dg/goacc/routine-2.C: Update.
diff --git gcc/testsuite/gfortran.dg/goacc/pr72741-intrinsic-1.f gcc/testsuite/gfortran.dg/goacc/pr72741-intrinsic-1.f
new file mode 100644
index 0000000..4bff3e3
--- /dev/null
+++ gcc/testsuite/gfortran.dg/goacc/pr72741-intrinsic-1.f
@@ -0,0 +1,20 @@
+! Check for valid clauses with intrinsic function specified in !$ACC ROUTINE ( NAME ).
+
+      SUBROUTINE sub_1
+      IMPLICIT NONE
+!$ACC ROUTINE (ABORT)
+!$ACC ROUTINE (ABORT) SEQ
+
+      CALL ABORT
+      END SUBROUTINE sub_1
+
+      MODULE m_w_1
+      IMPLICIT NONE
+!$ACC ROUTINE (ABORT) SEQ
+!$ACC ROUTINE (ABORT)
+
+      CONTAINS
+      SUBROUTINE sub_2
+      CALL ABORT
+      END SUBROUTINE sub_2
+      END MODULE m_w_1
diff --git gcc/testsuite/gfortran.dg/goacc/pr72741-intrinsic-2.f gcc/testsuite/gfortran.dg/goacc/pr72741-intrinsic-2.f
new file mode 100644
index 0000000..fed8e76
--- /dev/null
+++ gcc/testsuite/gfortran.dg/goacc/pr72741-intrinsic-2.f
@@ -0,0 +1,22 @@
+! Check for invalid clauses with intrinsic function specified in !$ACC ROUTINE ( NAME ).
+
+      SUBROUTINE sub_1
+      IMPLICIT NONE
+!$ACC ROUTINE (ABORT) WORKER ! { dg-error "Intrinsic function specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\), with incompatible GANG, WORKER, or VECTOR clause" }
+!$ACC ROUTINE (ABORT) GANG ! { dg-error "Intrinsic function specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\), with incompatible GANG, WORKER, or VECTOR clause" }
+!$ACC ROUTINE (ABORT) VECTOR ! { dg-error "Intrinsic function specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\), with incompatible GANG, WORKER, or VECTOR clause" }
+
+      CALL ABORT
+      END SUBROUTINE sub_1
+
+      MODULE m_w_1
+      IMPLICIT NONE
+!$ACC ROUTINE (ABORT) VECTOR ! { dg-error "Intrinsic function specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\), with incompatible GANG, WORKER, or VECTOR clause" }
+!$ACC ROUTINE (ABORT) WORKER ! { dg-error "Intrinsic function specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\), with incompatible GANG, WORKER, or VECTOR clause" }
+!$ACC ROUTINE (ABORT) GANG ! { dg-error "Intrinsic function specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\), with incompatible GANG, WORKER, or VECTOR clause" }
+
+      CONTAINS
+      SUBROUTINE sub_2
+      CALL ABORT
+      END SUBROUTINE sub_2
+      END MODULE m_w_1


Grüße
 Thomas

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [gomp4] Fix an ICE involving OpenACC routines inside broken fortran functions.
@ 2017-04-27 22:54 ` Cesar Philippidis
  2016-08-12 16:16   ` [PR fortran/72741] Handle intrinsic functions specified in !$ACC ROUTINE ( NAME ) Thomas Schwinge
  0 siblings, 1 reply; 4+ messages in thread
From: Cesar Philippidis @ 2017-04-27 22:54 UTC (permalink / raw)
  To: gcc-patches, Fortran List

[-- Attachment #1: Type: text/plain, Size: 645 bytes --]

I encountered an ICE when the fortran FE tries to parse an OpenACC
routine directive when the containing function has a syntax error. E.g.

  integer function f1

is missing an argument list, so the fortran FE will not create a
function symbol for f1. Consequently, the OpenACC routine parser cannot
register the routine directive with any function, so it hit a
gcc_unreachable.

This patch replaces that gcc_unreachable with a match_error. While the
syntax of the routine directive may be correct, it is still an error to
have a dangling acc routine directive not associated with a function.

I've applied this patch to gomp-4_0-branch.

Cesar

[-- Attachment #2: gomp4-broken-routine-ice.diff --]
[-- Type: text/x-patch, Size: 1234 bytes --]

2017-04-27  Cesar Philippidis  <cesar@codesourcery.com>

	gcc/fortran/
	* openmp.c (gfc_match_oacc_routine): Don't match OpenACC routines
	when the current function failed to parse due to a syntax error.

	gcc/testsuite/
	* gfortran.dg/goacc/routine-10.f90: New test.


diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index 0aecda4..72c6669 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -2576,7 +2576,9 @@ gfc_match_oacc_routine (void)
 	goto cleanup;
     }
   else
-    gcc_unreachable ();
+    /* Something has gone wrong.  Perhaps there was a syntax error
+       in the program-stmt.  */
+    goto cleanup;
 
   if (n)
     n->clauses = c;
diff --git a/gcc/testsuite/gfortran.dg/goacc/routine-10.f90 b/gcc/testsuite/gfortran.dg/goacc/routine-10.f90
new file mode 100644
index 0000000..4d8b5ba
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/routine-10.f90
@@ -0,0 +1,8 @@
+! Ensure that GFortran doesn't ICE with incomplete function
+! definitions.
+
+! { dg-do compile }
+
+integer function f1 ! { dg-error "Expected formal argument list in function definition" }
+  !$acc routine ! { dg-error "Unclassifiable OpenACC directive" }
+end function f1 ! { dg-error "Expecting END PROGRAM statement" }

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [patch,openacc] Check clauses with intrinsic function specified in !$ACC ROUTINE ( NAME )
@ 2018-10-02 15:06 Cesar Philippidis
  2017-04-27 22:54 ` [gomp4] Fix an ICE involving OpenACC routines inside broken fortran functions Cesar Philippidis
  0 siblings, 1 reply; 4+ messages in thread
From: Cesar Philippidis @ 2018-10-02 15:06 UTC (permalink / raw)
  To: Fortran List, gcc-patches, Schwinge, Thomas

[-- Attachment #1: Type: text/plain, Size: 558 bytes --]

This patch allows Fortran intrinsic functions to be declared as acc
routines. For instance, abort can now be called from acc within
offloaded regions.

Given that intrinsic functions like sin and cos are important for
offloaded functions, I wonder if there is a better way to accomplish to
enabling this. Maybe certain intrinsic functions should default to
having an implied acc routine directive. But I suppose that's something
for another patch.

Is this OK for trunk? I bootstrapped and regtested it for x86_64 Linux
with nvptx offloading.

Thanks,
Cesar

[-- Attachment #2: 0006-PR-fortran-72741-Check-clauses-with-intrinsic-functi.patch --]
[-- Type: text/x-patch, Size: 11412 bytes --]

[PR fortran/72741] Check clauses with intrinsic function specified in !$ACC ROUTINE ( NAME )

2018-XX-YY  Cesar Philippidis  <cesar@codesourcery.com>

	gcc/fortran/
	* openmp.c (gfc_match_oacc_routine): Check clauses of intrinsic
	functions.

	gcc/testsuite/
	* gfortran.dg/goacc/fixed-1.f: Update test.
	* gfortran.dg/goacc/pr72741-2.f: New test.
	* gfortran.dg/goacc/pr72741-intrinsic-1.f: New test.
	* gfortran.dg/goacc/pr72741-intrinsic-2.f: New test.
	* gfortran.dg/goacc/pr72741.f90: Update test.

	libgomp/
	* testsuite/libgomp.oacc-fortran/abort-1.f90: Update test.
	* testsuite/libgomp.oacc-fortran/acc_on_device-1-2.f: Update test.

(cherry picked from gomp-4_0-branch r239422)
(cherry picked from gomp-4_0-branch r239515, and r247954)
---
 gcc/fortran/openmp.c                          | 41 +++++++++++++++----
 gcc/testsuite/gfortran.dg/goacc/fixed-1.f     |  2 +
 gcc/testsuite/gfortran.dg/goacc/pr72741-2.f   | 39 ++++++++++++++++++
 .../gfortran.dg/goacc/pr72741-intrinsic-1.f   | 16 ++++++++
 .../gfortran.dg/goacc/pr72741-intrinsic-2.f   | 22 ++++++++++
 gcc/testsuite/gfortran.dg/goacc/pr72741.f90   | 20 +++++++--
 .../libgomp.oacc-fortran/abort-1.f90          |  1 +
 .../libgomp.oacc-fortran/acc_on_device-1-2.f  |  1 +
 8 files changed, 130 insertions(+), 12 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/goacc/pr72741-2.f
 create mode 100644 gcc/testsuite/gfortran.dg/goacc/pr72741-intrinsic-1.f
 create mode 100644 gcc/testsuite/gfortran.dg/goacc/pr72741-intrinsic-2.f

diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index 60ecaf54523..58cbe0ae90c 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -2288,8 +2288,9 @@ match
 gfc_match_oacc_routine (void)
 {
   locus old_loc;
-  gfc_symbol *sym = NULL;
   match m;
+  gfc_intrinsic_sym *isym = NULL;
+  gfc_symbol *sym = NULL;
   gfc_omp_clauses *c = NULL;
   gfc_oacc_routine_name *n = NULL;
   oacc_function dims;
@@ -2311,12 +2312,14 @@ gfc_match_oacc_routine (void)
   if (m == MATCH_YES)
     {
       char buffer[GFC_MAX_SYMBOL_LEN + 1];
-      gfc_symtree *st;
+      gfc_symtree *st = NULL;
 
       m = gfc_match_name (buffer);
       if (m == MATCH_YES)
 	{
-	  st = gfc_find_symtree (gfc_current_ns->sym_root, buffer);
+	  if ((isym = gfc_find_function (buffer)) == NULL
+	      && (isym = gfc_find_subroutine (buffer)) == NULL)
+	    st = gfc_find_symtree (gfc_current_ns->sym_root, buffer);
 	  if (st)
 	    {
 	      sym = st->n.sym;
@@ -2325,7 +2328,7 @@ gfc_match_oacc_routine (void)
 	        sym = NULL;
 	    }
 
-	  if (st == NULL
+	  if ((isym == NULL && st == NULL)
 	      || (sym
 		  && !sym->attr.external
 		  && !sym->attr.function
@@ -2337,6 +2340,13 @@ gfc_match_oacc_routine (void)
 	      gfc_current_locus = old_loc;
 	      return MATCH_ERROR;
 	    }
+
+	  /* Set sym to NULL if it matches the current procedure's
+	     name.  This will simplify the check for duplicate ACC
+	     ROUTINE attributes.  */
+	  if (gfc_current_ns->proc_name
+	      && !strcmp (buffer, gfc_current_ns->proc_name->name))
+	    sym = NULL;
 	}
       else
         {
@@ -2357,15 +2367,30 @@ gfc_match_oacc_routine (void)
 	  != MATCH_YES))
     return MATCH_ERROR;
 
+  /* Scan for invalid routine geometry.  */
   dims = gfc_oacc_routine_dims (c);
   if (dims == OACC_FUNCTION_NONE)
     {
-      gfc_error ("Multiple loop axes specified for routine %C");
-      gfc_current_locus = old_loc;
-      return MATCH_ERROR;
+      gfc_error ("Multiple loop axes specified in !$ACC ROUTINE at %C");
+
+      /* Don't abort early, because it's important to let the user
+	 know of any potential duplicate routine directives.  */
+      seen_error = true;
     }
 
-  if (sym != NULL)
+  if (isym != NULL)
+    {
+      if (c && (c->gang || c->worker || c->vector))
+	{
+	  gfc_error ("Intrinsic symbol specified in !$ACC ROUTINE ( NAME ) "
+		     "at %C, with incompatible clauses specifying the level "
+		     "of parallelism");
+	  goto cleanup;
+	}
+      /* The intrinsic symbol has been marked with a SEQ, or with no clause at
+	 all, which is OK.  */
+    }
+  else if (sym != NULL)
     {
       bool needs_entry = true;
 
diff --git a/gcc/testsuite/gfortran.dg/goacc/fixed-1.f b/gcc/testsuite/gfortran.dg/goacc/fixed-1.f
index 974f2702260..3a900c5b4e6 100644
--- a/gcc/testsuite/gfortran.dg/goacc/fixed-1.f
+++ b/gcc/testsuite/gfortran.dg/goacc/fixed-1.f
@@ -1,3 +1,5 @@
+!$ACC ROUTINE(ABORT) SEQ
+
       INTEGER :: ARGC
       ARGC = COMMAND_ARGUMENT_COUNT ()
 
diff --git a/gcc/testsuite/gfortran.dg/goacc/pr72741-2.f b/gcc/testsuite/gfortran.dg/goacc/pr72741-2.f
new file mode 100644
index 00000000000..58651440d20
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/pr72741-2.f
@@ -0,0 +1,39 @@
+      SUBROUTINE v_1
+!$ACC ROUTINE
+!$ACC ROUTINE ! { dg-error "ACC ROUTINE already applied" }
+!$ACC ROUTINE GANG ! { dg-error "ACC ROUTINE already applied" }
+!$ACC ROUTINE SEQ ! { dg-error "ACC ROUTINE already applied" }
+!$ACC ROUTINE ! { dg-error "ACC ROUTINE already applied" }
+!$ACC ROUTINE WORKER ! { dg-error "ACC ROUTINE already applied" }
+      END SUBROUTINE v_1
+
+      SUBROUTINE sub_1
+      IMPLICIT NONE
+      EXTERNAL :: g_1
+!$ACC ROUTINE (g_1) GANG
+!$ACC ROUTINE (g_1) VECTOR ! { dg-error "ACC ROUTINE already applied" }
+!$ACC ROUTINE (g_1) SEQ ! { dg-error "ACC ROUTINE already applied" }
+!$ACC ROUTINE (g_1) ! { dg-error "ACC ROUTINE already applied" }
+!$ACC ROUTINE (g_1) ! { dg-error "ACC ROUTINE already applied" }
+
+      CALL v_1
+      CALL g_1
+      CALL ABORT
+      END SUBROUTINE sub_1
+
+      MODULE m_w_1
+      IMPLICIT NONE
+      EXTERNAL :: w_1
+!$ACC ROUTINE (w_1) WORKER
+!$ACC ROUTINE (w_1) ! { dg-error "ACC ROUTINE already applied" }
+!$ACC ROUTINE (w_1) SEQ ! { dg-error "ACC ROUTINE already applied" }
+!$ACC ROUTINE (w_1) ! { dg-error "ACC ROUTINE already applied" }
+!$ACC ROUTINE (w_1) VECTOR ! { dg-error "ACC ROUTINE already applied" }
+
+      CONTAINS
+      SUBROUTINE sub_2
+      CALL v_1
+      CALL w_1
+      CALL ABORT
+      END SUBROUTINE sub_2
+      END MODULE m_w_1
diff --git a/gcc/testsuite/gfortran.dg/goacc/pr72741-intrinsic-1.f b/gcc/testsuite/gfortran.dg/goacc/pr72741-intrinsic-1.f
new file mode 100644
index 00000000000..d84cdf9d0a8
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/pr72741-intrinsic-1.f
@@ -0,0 +1,16 @@
+      SUBROUTINE sub_1
+      IMPLICIT NONE
+!$ACC ROUTINE (ABORT) SEQ VECTOR ! { dg-error "Intrinsic symbol specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\), with incompatible clauses specifying the level of parallelism" }
+
+      CALL ABORT
+      END SUBROUTINE sub_1
+
+      MODULE m_w_1
+      IMPLICIT NONE
+!$ACC ROUTINE (ABORT) VECTOR GANG ! { dg-error "Intrinsic symbol specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\), with incompatible clauses specifying the level of parallelism" }
+
+      CONTAINS
+      SUBROUTINE sub_2
+      CALL ABORT
+      END SUBROUTINE sub_2
+      END MODULE m_w_1
diff --git a/gcc/testsuite/gfortran.dg/goacc/pr72741-intrinsic-2.f b/gcc/testsuite/gfortran.dg/goacc/pr72741-intrinsic-2.f
new file mode 100644
index 00000000000..e5e3794d1c5
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/pr72741-intrinsic-2.f
@@ -0,0 +1,22 @@
+! Check for invalid clauses with intrinsic function specified in !$ACC ROUTINE ( NAME ).
+
+      SUBROUTINE sub_1
+      IMPLICIT NONE
+!$ACC ROUTINE (ABORT) WORKER ! { dg-error "Intrinsic symbol specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\), with incompatible clauses specifying the level of parallelism" }
+!$ACC ROUTINE (ABORT) GANG ! { dg-error "Intrinsic symbol specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\), with incompatible clauses specifying the level of parallelism" }
+!$ACC ROUTINE (ABORT) VECTOR ! { dg-error "Intrinsic symbol specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\), with incompatible clauses specifying the level of parallelism" }
+
+      CALL ABORT
+      END SUBROUTINE sub_1
+
+      MODULE m_w_1
+      IMPLICIT NONE
+!$ACC ROUTINE (ABORT) VECTOR ! { dg-error "Intrinsic symbol specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\), with incompatible clauses specifying the level of parallelism" }
+!$ACC ROUTINE (ABORT) WORKER ! { dg-error "Intrinsic symbol specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\), with incompatible clauses specifying the level of parallelism" }
+!$ACC ROUTINE (ABORT) GANG ! { dg-error "Intrinsic symbol specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\), with incompatible clauses specifying the level of parallelism" }
+
+      CONTAINS
+      SUBROUTINE sub_2
+      CALL ABORT
+      END SUBROUTINE sub_2
+      END MODULE m_w_1
diff --git a/gcc/testsuite/gfortran.dg/goacc/pr72741.f90 b/gcc/testsuite/gfortran.dg/goacc/pr72741.f90
index b295a4fcc59..3fbd94f6f7d 100644
--- a/gcc/testsuite/gfortran.dg/goacc/pr72741.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/pr72741.f90
@@ -1,13 +1,24 @@
 SUBROUTINE v_1
   !$ACC ROUTINE VECTOR WORKER ! { dg-error "Multiple loop axes" }
+  !$ACC ROUTINE VECTOR ! { dg-error "ACC ROUTINE already applied" }
+  !$ACC ROUTINE ! { dg-error "ACC ROUTINE already applied" }
+  !$ACC ROUTINE GANG VECTOR ! { dg-error "Multiple loop axes" }
 END SUBROUTINE v_1
 
+SUBROUTINE v_2
+  !$ACC ROUTINE(v_2) VECTOR WORKER ! { dg-error "Multiple loop axes" }
+  !$ACC ROUTINE(v_2) VECTOR ! { dg-error "ACC ROUTINE already applied" }
+  !$ACC ROUTINE(v_2) ! { dg-error "ACC ROUTINE already applied" }
+  !$ACC ROUTINE(v_2) GANG VECTOR ! { dg-error "Multiple loop axes" }
+END SUBROUTINE v_2
+
 SUBROUTINE sub_1
   IMPLICIT NONE
   EXTERNAL :: g_1
   !$ACC ROUTINE (g_1) GANG WORKER ! { dg-error "Multiple loop axes" }
-  !$ACC ROUTINE (ABORT) SEQ VECTOR ! { dg-error "Multiple loop axes" "" { xfail *-*-* } }
-! { dg-bogus "invalid function name abort" "" { xfail *-*-* } .-1 }
+  !$ACC ROUTINE (g_1) GANG ! { dg-error "ACC ROUTINE already applied" }
+  !$ACC ROUTINE (g_1) ! { dg-error "ACC ROUTINE already applied" }
+  !$ACC ROUTINE (g_1) VECTOR GANG ! { dg-error "Multiple loop axes" }
 
   CALL v_1
   CALL g_1
@@ -18,8 +29,9 @@ MODULE m_w_1
   IMPLICIT NONE
   EXTERNAL :: w_1
   !$ACC ROUTINE (w_1) WORKER SEQ ! { dg-error "Multiple loop axes" }
-  !$ACC ROUTINE (ABORT) VECTOR GANG ! { dg-error "Multiple loop axes" "" { xfail *-*-* } }
-! { dg-bogus "invalid function name abort" "" { xfail *-*-* } .-1 }
+  !$ACC ROUTINE (w_1) WORKER ! { dg-error "ACC ROUTINE already applied" }
+  !$ACC ROUTINE (w_1) ! { dg-error "ACC ROUTINE already applied" }
+  !$ACC ROUTINE (w_1) VECTOR WORKER ! { dg-error "Multiple loop axes" }
 
 CONTAINS
   SUBROUTINE sub_2
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/abort-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/abort-1.f90
index fc0af7ff7d8..cfe505ecb76 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/abort-1.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/abort-1.f90
@@ -3,6 +3,7 @@
 
 program main
   implicit none
+  !$acc routine(abort) seq
 
   print *, "CheCKpOInT"
   !$acc parallel
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-2.f b/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-2.f
index 75e24509ce9..d81ff1bd9ab 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-2.f
+++ b/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-2.f
@@ -6,6 +6,7 @@
 
       USE OPENACC
       IMPLICIT NONE
+!$ACC ROUTINE(ABORT) SEQ
 
 !Host.
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PR72741, PR89433] Accept intrinsic symbols in Fortran OpenACC 'routine' directives
  2016-08-12 16:16   ` [PR fortran/72741] Handle intrinsic functions specified in !$ACC ROUTINE ( NAME ) Thomas Schwinge
@ 2019-02-28 20:37     ` Thomas Schwinge
  0 siblings, 0 replies; 4+ messages in thread
From: Thomas Schwinge @ 2019-02-28 20:37 UTC (permalink / raw)
  To: gcc-patches, fortran


[-- Attachment #1.1: Type: text/plain, Size: 630 bytes --]

Hi!

On Fri, 12 Aug 2016 18:13:43 +0200, I wrote:
> Let me actually break this out of the other pending patches; this should
> be uncontroversial.  Originally by Cesar, extended by me.  OK for trunk?
> 
> commit a0fee96c0f204814e87ddf6635f9cbec2afc6887
> Author: Thomas Schwinge <thomas@codesourcery.com>
> Date:   Fri Aug 12 17:19:05 2016 +0200
> 
>     [PR fortran/72741] Handle intrinsic functions specified in !$ACC ROUTINE ( NAME )

Re-worked a bit, and committed to trunk in r269285 "[PR72741, PR89433]
Accept intrinsic symbols in Fortran OpenACC 'routine' directives", as
attached.


Grüße
 Thomas



[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: 0001-PR72741-PR89433-Accept-intrinsic-symbols-in-Fortran-.patch --]
[-- Type: text/x-diff, Size: 7790 bytes --]

From 1d86d0eb3e7b6c3d799c91fad4bc12da572160fd Mon Sep 17 00:00:00 2001
From: tschwinge <tschwinge@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Thu, 28 Feb 2019 20:31:01 +0000
Subject: [PATCH 1/3] [PR72741, PR89433] Accept intrinsic symbols in Fortran
 OpenACC 'routine' directives

	gcc/fortran/
	PR fortran/72741
	PR fortran/89433
	* openmp.c (gfc_match_oacc_routine): Accept intrinsic symbols.
	gcc/testsuite/
	PR fortran/72741
	PR fortran/89433
	* gfortran.dg/goacc/routine-6.f90: Update
	* gfortran.dg/goacc/routine-intrinsic-1.f: New file.
	* gfortran.dg/goacc/routine-intrinsic-2.f: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@269285 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/fortran/ChangeLog                         |  7 ++++
 gcc/fortran/openmp.c                          | 33 ++++++++++++++++---
 gcc/testsuite/ChangeLog                       |  9 +++++
 gcc/testsuite/gfortran.dg/goacc/routine-6.f90 |  7 ++++
 .../gfortran.dg/goacc/routine-intrinsic-1.f   | 21 ++++++++++++
 .../gfortran.dg/goacc/routine-intrinsic-2.f   | 23 +++++++++++++
 6 files changed, 95 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/goacc/routine-intrinsic-1.f
 create mode 100644 gcc/testsuite/gfortran.dg/goacc/routine-intrinsic-2.f

diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 85ce5bce5604..78c6324d1b83 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,10 @@
+2019-02-28  Thomas Schwinge  <thomas@codesourcery.com>
+	    Cesar Philippidis  <cesar@codesourcery.com>
+
+	PR fortran/72741
+	PR fortran/89433
+	* openmp.c (gfc_match_oacc_routine): Accept intrinsic symbols.
+
 2019-02-26  Harald Anlauf  <anlauf@gmx.de>
 
 	PR fortran/89492
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index dfd4be86d50e..6999ac34a1a9 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -2275,8 +2275,9 @@ match
 gfc_match_oacc_routine (void)
 {
   locus old_loc;
-  gfc_symbol *sym = NULL;
   match m;
+  gfc_intrinsic_sym *isym = NULL;
+  gfc_symbol *sym = NULL;
   gfc_omp_clauses *c = NULL;
   gfc_oacc_routine_name *n = NULL;
 
@@ -2296,12 +2297,19 @@ gfc_match_oacc_routine (void)
   if (m == MATCH_YES)
     {
       char buffer[GFC_MAX_SYMBOL_LEN + 1];
-      gfc_symtree *st;
 
       m = gfc_match_name (buffer);
       if (m == MATCH_YES)
 	{
-	  st = gfc_find_symtree (gfc_current_ns->sym_root, buffer);
+	  gfc_symtree *st = NULL;
+
+	  /* First look for an intrinsic symbol.  */
+	  isym = gfc_find_function (buffer);
+	  if (!isym)
+	    isym = gfc_find_subroutine (buffer);
+	  /* If no intrinsic symbol found, search the current namespace.  */
+	  if (!isym)
+	    st = gfc_find_symtree (gfc_current_ns->sym_root, buffer);
 	  if (st)
 	    {
 	      sym = st->n.sym;
@@ -2310,7 +2318,7 @@ gfc_match_oacc_routine (void)
 	        sym = NULL;
 	    }
 
-	  if (st == NULL
+	  if ((isym == NULL && st == NULL)
 	      || (sym
 		  && !sym->attr.external
 		  && !sym->attr.function
@@ -2344,7 +2352,19 @@ gfc_match_oacc_routine (void)
 	  != MATCH_YES))
     return MATCH_ERROR;
 
-  if (sym != NULL)
+  if (isym != NULL)
+    {
+      /* Diagnose any OpenACC 'routine' directive that doesn't match the
+	 (implicit) one with a 'seq' clause.  */
+      if (c && (c->gang || c->worker || c->vector))
+	{
+	  gfc_error ("Intrinsic symbol specified in !$ACC ROUTINE ( NAME )"
+		     " at %C marked with incompatible GANG, WORKER, or VECTOR"
+		     " clause");
+	  goto cleanup;
+	}
+    }
+  else if (sym != NULL)
     {
       n = gfc_get_oacc_routine_name ();
       n->sym = sym;
@@ -2364,6 +2384,9 @@ gfc_match_oacc_routine (void)
       gfc_current_ns->proc_name->attr.oacc_routine_lop
 	= gfc_oacc_routine_lop (c);
     }
+  else
+    /* Something has gone wrong, possibly a syntax error.  */
+    goto cleanup;
 
   if (n)
     n->clauses = c;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 79de60324e3b..c45e7b7546a9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2019-02-28  Thomas Schwinge  <thomas@codesourcery.com>
+	    Cesar Philippidis  <cesar@codesourcery.com>
+
+	PR fortran/72741
+	PR fortran/89433
+	* gfortran.dg/goacc/routine-6.f90: Update
+	* gfortran.dg/goacc/routine-intrinsic-1.f: New file.
+	* gfortran.dg/goacc/routine-intrinsic-2.f: Likewise.
+
 2019-02-28  Jakub Jelinek  <jakub@redhat.com>
 
 	PR c/89521
diff --git a/gcc/testsuite/gfortran.dg/goacc/routine-6.f90 b/gcc/testsuite/gfortran.dg/goacc/routine-6.f90
index 10943cff3045..0201b8d1fee5 100644
--- a/gcc/testsuite/gfortran.dg/goacc/routine-6.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/routine-6.f90
@@ -1,3 +1,4 @@
+! Check for invalid syntax with !$ACC ROUTINE.
 
 module m
   integer m1int
@@ -45,6 +46,12 @@ program main
   !$acc end parallel
 end program main
 
+! Ensure that we recover from incomplete function definitions.
+
+integer function f1 ! { dg-error "Expected formal argument list in function definition" }
+  !$acc routine ! { dg-error "Unclassifiable OpenACC directive" }
+end function f1 ! { dg-error "Expecting END PROGRAM statement" }
+
 subroutine subr1 (x) 
   !$acc routine
   integer, intent(inout) :: x
diff --git a/gcc/testsuite/gfortran.dg/goacc/routine-intrinsic-1.f b/gcc/testsuite/gfortran.dg/goacc/routine-intrinsic-1.f
new file mode 100644
index 000000000000..5dab573a9966
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/routine-intrinsic-1.f
@@ -0,0 +1,21 @@
+! Check for valid clauses with intrinsic symbols specified in OpenACC
+! 'routine' directives.
+
+      SUBROUTINE sub_1
+      IMPLICIT NONE
+!$ACC ROUTINE (ABORT)
+!$ACC ROUTINE (ABORT) SEQ
+
+      CALL ABORT
+      END SUBROUTINE sub_1
+
+      MODULE m_w_1
+      IMPLICIT NONE
+!$ACC ROUTINE (ABORT) SEQ
+!$ACC ROUTINE (ABORT)
+
+      CONTAINS
+      SUBROUTINE sub_2
+      CALL ABORT
+      END SUBROUTINE sub_2
+      END MODULE m_w_1
diff --git a/gcc/testsuite/gfortran.dg/goacc/routine-intrinsic-2.f b/gcc/testsuite/gfortran.dg/goacc/routine-intrinsic-2.f
new file mode 100644
index 000000000000..22524cc16451
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/routine-intrinsic-2.f
@@ -0,0 +1,23 @@
+! Check for invalid clauses with intrinsic symbols specified in OpenACC
+! 'routine' directives.
+
+      SUBROUTINE sub_1
+      IMPLICIT NONE
+!$ACC ROUTINE (ABORT) WORKER ! { dg-error "Intrinsic symbol specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\) marked with incompatible GANG, WORKER, or VECTOR clause" }
+!$ACC ROUTINE (ABORT) GANG ! { dg-error "Intrinsic symbol specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\) marked with incompatible GANG, WORKER, or VECTOR clause" }
+!$ACC ROUTINE (ABORT) VECTOR ! { dg-error "Intrinsic symbol specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\) marked with incompatible GANG, WORKER, or VECTOR clause" }
+
+      CALL ABORT
+      END SUBROUTINE sub_1
+
+      MODULE m_w_1
+      IMPLICIT NONE
+!$ACC ROUTINE (ABORT) VECTOR ! { dg-error "Intrinsic symbol specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\) marked with incompatible GANG, WORKER, or VECTOR clause" }
+!$ACC ROUTINE (ABORT) WORKER ! { dg-error "Intrinsic symbol specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\) marked with incompatible GANG, WORKER, or VECTOR clause" }
+!$ACC ROUTINE (ABORT) GANG ! { dg-error "Intrinsic symbol specified in \\!\\\$ACC ROUTINE \\( NAME \\) at \\(1\\) marked with incompatible GANG, WORKER, or VECTOR clause" }
+
+      CONTAINS
+      SUBROUTINE sub_2
+      CALL ABORT
+      END SUBROUTINE sub_2
+      END MODULE m_w_1
-- 
2.17.1


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 658 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-02-28 20:34 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-02 15:06 [patch,openacc] Check clauses with intrinsic function specified in !$ACC ROUTINE ( NAME ) Cesar Philippidis
2017-04-27 22:54 ` [gomp4] Fix an ICE involving OpenACC routines inside broken fortran functions Cesar Philippidis
2016-08-12 16:16   ` [PR fortran/72741] Handle intrinsic functions specified in !$ACC ROUTINE ( NAME ) Thomas Schwinge
2019-02-28 20:37     ` [PR72741, PR89433] Accept intrinsic symbols in Fortran OpenACC 'routine' directives Thomas Schwinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).