PR85463 '[nvptx] "exit" in offloaded region doesn't terminate process' (was: [patch, libfortran, committed] Implement stop_numeric for minimal targets)

Message ID 87in8nsgz9.fsf@euler.schwinge.homeip.net
State New
Headers show
Series
  • PR85463 '[nvptx] "exit" in offloaded region doesn't terminate process' (was: [patch, libfortran, committed] Implement stop_numeric for minimal targets)
Related show

Commit Message

Thomas Schwinge April 19, 2018, 9:06 a.m.
Hi!

On Wed, 4 Apr 2018 11:30:34 +0200, Thomas König <tk@tkoenig.net> wrote:
> the recent patch to make the gfortran and libgomp testsuites more

> standard conforming, by replacing CALL ABORT() with STOP N, led

> to numerous testsuite failures on nvptx because stop_numeric

> was not implemented in minimal.c.

> 

> I have committed the patch below in r259072 as obvious after Tom

> de Vries had confirmed that it solves the problem.


... for some meaning of "solves the problem"; see below.  ;-) Which you
couldn't know, of course.  (So, definitely thanks anyway, for promptly
addressing the issue raised!)

> --- runtime/minimal.c	(Revision 259055)

> +++ runtime/minimal.c	(Arbeitskopie)


> +void

> +stop_numeric (int code, bool quiet)

> +{

> +  if (!quiet)

> +    printf ("STOP %d\n", code);

> +

> +  exit (code);

> +}


Per PR85463 '[nvptx] "exit" in offloaded region doesn't terminate
process' that I just filed, we currently have to use "abort" instead of
"exit" for nvptx offloading, so I have applied the following in trunk
r259491, where I completed this by adding and testing stop_string,
error_stop_string, and error_stop_numeric functions, too.

commit 6bc09e4fa2e5e59dee18f1c03f2d6529b9b0045b
Author: tschwinge <tschwinge@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Thu Apr 19 08:53:38 2018 +0000

    PR85463 '[nvptx] "exit" in offloaded region doesn't terminate process'
    
            libgomp/
            PR libfortran/85166
            * testsuite/libgomp.oacc-fortran/abort-1.f90: Switch back to "call
            abort".
            * testsuite/libgomp.oacc-fortran/abort-2.f90: Likewise.
    
            libgfortran/
            PR libfortran/85166
            PR libgomp/85463
            * runtime/minimal.c (stop_numeric): Reimplement.
            (stop_string, error_stop_string, error_stop_numeric): New
            functions.
            libgomp/
            PR libgomp/85463
            * testsuite/libgomp.oacc-fortran/error_stop-1.f: New file.
            * testsuite/libgomp.oacc-fortran/error_stop-2.f: Likewise.
            * testsuite/libgomp.oacc-fortran/error_stop-3.f: Likewise.
            * testsuite/libgomp.oacc-fortran/stop-1.f: Likewise.
            * testsuite/libgomp.oacc-fortran/stop-2.f: Likewise.
            * testsuite/libgomp.oacc-fortran/stop-3.f: Likewise.
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@259491 138bc75d-0d04-0410-961f-82ee72b054a4
---
 libgfortran/ChangeLog                              |  8 +++
 libgfortran/runtime/minimal.c                      | 80 +++++++++++++++++++++-
 libgomp/ChangeLog                                  | 15 ++++
 libgomp/testsuite/libgomp.oacc-fortran/abort-1.f90 |  5 +-
 libgomp/testsuite/libgomp.oacc-fortran/abort-2.f90 |  5 +-
 .../testsuite/libgomp.oacc-fortran/error_stop-1.f  | 20 ++++++
 .../testsuite/libgomp.oacc-fortran/error_stop-2.f  | 20 ++++++
 .../testsuite/libgomp.oacc-fortran/error_stop-3.f  | 20 ++++++
 libgomp/testsuite/libgomp.oacc-fortran/stop-1.f    | 22 ++++++
 libgomp/testsuite/libgomp.oacc-fortran/stop-2.f    | 20 ++++++
 libgomp/testsuite/libgomp.oacc-fortran/stop-3.f    | 23 +++++++
 11 files changed, 234 insertions(+), 4 deletions(-)



Grüße
 Thomas

Comments

Jakub Jelinek April 19, 2018, 9:14 a.m. | #1
On Thu, Apr 19, 2018 at 11:06:18AM +0200, Thomas Schwinge wrote:
> Hi!

> 

> On Wed, 4 Apr 2018 11:30:34 +0200, Thomas König <tk@tkoenig.net> wrote:

> > the recent patch to make the gfortran and libgomp testsuites more

> > standard conforming, by replacing CALL ABORT() with STOP N, led

> > to numerous testsuite failures on nvptx because stop_numeric

> > was not implemented in minimal.c.

> > 

> > I have committed the patch below in r259072 as obvious after Tom

> > de Vries had confirmed that it solves the problem.

> 

> ... for some meaning of "solves the problem"; see below.  ;-) Which you

> couldn't know, of course.  (So, definitely thanks anyway, for promptly

> addressing the issue raised!)


My preference would be just to revert the call abort to stop n changes
in target regions.
Mapping exit to abort is weird, and making exit terminate whole process even
when called from offloaded regions might be too expensive.

	Jakub
Thomas Schwinge April 19, 2018, 9:19 a.m. | #2
Hi!

On Thu, 19 Apr 2018 11:14:38 +0200, Jakub Jelinek <jakub@redhat.com> wrote:
> On Thu, Apr 19, 2018 at 11:06:18AM +0200, Thomas Schwinge wrote:

> > On Wed, 4 Apr 2018 11:30:34 +0200, Thomas König <tk@tkoenig.net> wrote:

> > > the recent patch to make the gfortran and libgomp testsuites more

> > > standard conforming, by replacing CALL ABORT() with STOP N, led

> > > to numerous testsuite failures on nvptx because stop_numeric

> > > was not implemented in minimal.c.

> > > 

> > > I have committed the patch below in r259072 as obvious after Tom

> > > de Vries had confirmed that it solves the problem.

> > 

> > ... for some meaning of "solves the problem"; see below.  ;-) Which you

> > couldn't know, of course.  (So, definitely thanks anyway, for promptly

> > addressing the issue raised!)

> 

> My preference would be just to revert the call abort to stop n changes

> in target regions.


That seems backwards to me -- having "exit" (as well as Fortran language
"stop" and "error stop") inside offloaded regions do the right thing is
something we wanted to do anyway, eventually.

> Mapping exit to abort is weird


Sure, that's why PR85463 is still open, and has some (initial)
comments/ideas regarding that.

> and making exit terminate whole process even

> when called from offloaded regions might be too expensive.


In what way "too expensive"?


Grüße
 Thomas
Jakub Jelinek April 19, 2018, 9:25 a.m. | #3
On Thu, Apr 19, 2018 at 11:19:31AM +0200, Thomas Schwinge wrote:
> Hi!

> 

> On Thu, 19 Apr 2018 11:14:38 +0200, Jakub Jelinek <jakub@redhat.com> wrote:

> > On Thu, Apr 19, 2018 at 11:06:18AM +0200, Thomas Schwinge wrote:

> > > On Wed, 4 Apr 2018 11:30:34 +0200, Thomas König <tk@tkoenig.net> wrote:

> > > > the recent patch to make the gfortran and libgomp testsuites more

> > > > standard conforming, by replacing CALL ABORT() with STOP N, led

> > > > to numerous testsuite failures on nvptx because stop_numeric

> > > > was not implemented in minimal.c.

> > > > 

> > > > I have committed the patch below in r259072 as obvious after Tom

> > > > de Vries had confirmed that it solves the problem.

> > > 

> > > ... for some meaning of "solves the problem"; see below.  ;-) Which you

> > > couldn't know, of course.  (So, definitely thanks anyway, for promptly

> > > addressing the issue raised!)

> > 

> > My preference would be just to revert the call abort to stop n changes

> > in target regions.

> 

> That seems backwards to me -- having "exit" (as well as Fortran language

> "stop" and "error stop") inside offloaded regions do the right thing is

> something we wanted to do anyway, eventually.


I'm looking for a GCC8 fix, and for that it seems like the simplest
and safest solution.

> > Mapping exit to abort is weird

> 

> Sure, that's why PR85463 is still open, and has some (initial)

> comments/ideas regarding that.

> 

> > and making exit terminate whole process even

> > when called from offloaded regions might be too expensive.

> 

> In what way "too expensive"?


If you need to add code to handle that case to every target region entry
just in case something does stop, the slow down might be too high and
unacceptable.  Depends on how it is implemented.

	Jakub
Thomas Schwinge April 19, 2018, 9:36 a.m. | #4
Hi!

On Thu, 19 Apr 2018 11:25:30 +0200, Jakub Jelinek <jakub@redhat.com> wrote:
> On Thu, Apr 19, 2018 at 11:19:31AM +0200, Thomas Schwinge wrote:

> > On Thu, 19 Apr 2018 11:14:38 +0200, Jakub Jelinek <jakub@redhat.com> wrote:

> > > On Thu, Apr 19, 2018 at 11:06:18AM +0200, Thomas Schwinge wrote:

> > > > On Wed, 4 Apr 2018 11:30:34 +0200, Thomas König <tk@tkoenig.net> wrote:

> > > > > the recent patch to make the gfortran and libgomp testsuites more

> > > > > standard conforming, by replacing CALL ABORT() with STOP N, led

> > > > > to numerous testsuite failures on nvptx because stop_numeric

> > > > > was not implemented in minimal.c.

> > > > > 

> > > > > I have committed the patch below in r259072 as obvious after Tom

> > > > > de Vries had confirmed that it solves the problem.

> > > > 

> > > > ... for some meaning of "solves the problem"; see below.  ;-) Which you

> > > > couldn't know, of course.  (So, definitely thanks anyway, for promptly

> > > > addressing the issue raised!)

> > > 

> > > My preference would be just to revert the call abort to stop n changes

> > > in target regions.

> > 

> > That seems backwards to me -- having "exit" (as well as Fortran language

> > "stop" and "error stop") inside offloaded regions do the right thing is

> > something we wanted to do anyway, eventually.

> 

> I'm looking for a GCC8 fix, and for that it seems like the simplest

> and safest solution.


As far as I know, the "call abort to stop n" changes regressed nvptx
targets only, and that's now fixed (and improved to handle more Fortran
language "stop" and "error stop" variants), so I don't see a reason to
iterate once again?  (Or, why didn't you then already dispute Thomas
König's nvptx/libgfortran minimal.c patch adding stop_numeric?)


> > > Mapping exit to abort is weird

> > 

> > Sure, that's why PR85463 is still open, and has some (initial)

> > comments/ideas regarding that.

> > 

> > > and making exit terminate whole process even

> > > when called from offloaded regions might be too expensive.

> > 

> > In what way "too expensive"?

> 

> If you need to add code to handle that case to every target region entry

> just in case something does stop, the slow down might be too high and

> unacceptable.  Depends on how it is implemented.


Right, but that's again "why PR85463 is still open, and has some
(initial) comments/ideas regarding that", and no overhead has so far been
introduced.


Grüße
 Thomas
Thomas König April 19, 2018, 11:32 a.m. | #5
> Mapping exit to abort is weird,


For Fortran, this is mapping STOP with a numeric code to abort.

The Fortran standard does not apply in this case. What does the OpenACC standard say about STOP in an offloaded region?

Regards, Thomas
Thomas Schwinge April 19, 2018, 11:59 a.m. | #6
Hi!

On Thu, 19 Apr 2018 13:32:16 +0200, Thomas König <tk@tkoenig.net> wrote:
> > Mapping exit to abort is weird,

> 

> For Fortran, this is mapping STOP with a numeric code to abort.

> 

> The Fortran standard does not apply in this case. What does the OpenACC

> standard say about STOP in an offloaded region?


Nothing explicitly, as far as I know.  ;-/ Which means, that this either
a) has to be forbidden, or b) some common sense implementation is called
for.  Well, implicitly it's meant such that "standard Fortran language
usage" is supported inside such offloading regions.  And, as code like:

    !$ACC PARALLEL
    [compute A]
    if (.not. [sanity check computation A]) then
      stop 1
    end if
    [compute B, using A]
    !$ACC END PARALLEL
    [compute C, using A and B]

... certainly is a reasonable thing to support, option b) clearly is
preferrable over option a).  Before my patch, if "[sanity check
computation A]" failed, the offloading region would terminate normally,
without executing "[compute B, using A]", but would then erroneously
"[compute C, using A and B]" with bogus data, so mapping that offloading
region's "stop 1" to "abort" again is an improvement, to make the "sanity
check" error observable.


Grüße
 Thomas
Thomas König April 19, 2018, 5:59 p.m. | #7
Am 19.04.2018 um 13:59 schrieb Thomas Schwinge:
>> The Fortran standard does not apply in this case. What does the OpenACC

>> standard say about STOP in an offloaded region?

> Nothing explicitly, as far as I know.  ;-/ Which means, that this either

> a) has to be forbidden, or b) some common sense implementation is called

> for.  Well, implicitly it's meant such that "standard Fortran language

> usage" is supported inside such offloading regions.  And, as code like:

> 

>      !$ACC PARALLEL

>      [compute A]

>      if (.not. [sanity check computation A]) then

>        stop 1

>      end if

>      [compute B, using A]

>      !$ACC END PARALLEL

>      [compute C, using A and B]

> 

> ... certainly is a reasonable thing to support, option b) clearly is

> preferrable over option a).


Well, if the Fortran standard may be relevant after all, let's look
at what it has to say.

J3/10-007

# 8.4 STOP and ERROR STOP statements

# When an image is terminated by a STOP or ERROR STOP statement, its
# stop code, if any, is made available in a processor-dependent manner.

Well, an offloading region is not a Fortran image, but at least it is
something vaguely similar. Also, it is unclear to whom this stop code
is made available. Having said that, the spirit, if not the letter,
of this sentence certainly supports that something other than silently
ignoring the error should be done.

Regards

	Thomas
Martin Jambor April 25, 2018, 1:56 p.m. | #8
Hi,

On Thu, Apr 19 2018, Thomas Schwinge wrote:
>

> Per PR85463 '[nvptx] "exit" in offloaded region doesn't terminate

> process' that I just filed, we currently have to use "abort" instead of

> "exit" for nvptx offloading, so I have applied the following in trunk

> r259491, where I completed this by adding and testing stop_string,

> error_stop_string, and error_stop_numeric functions, too.

>

> commit 6bc09e4fa2e5e59dee18f1c03f2d6529b9b0045b

> Author: tschwinge <tschwinge@138bc75d-0d04-0410-961f-82ee72b054a4>

> Date:   Thu Apr 19 08:53:38 2018 +0000

>

>     PR85463 '[nvptx] "exit" in offloaded region doesn't terminate process'

>     

>             libgomp/

>             PR libfortran/85166

>             * testsuite/libgomp.oacc-fortran/abort-1.f90: Switch back to "call

>             abort".

>             * testsuite/libgomp.oacc-fortran/abort-2.f90: Likewise.

>     

>             libgfortran/

>             PR libfortran/85166

>             PR libgomp/85463

>             * runtime/minimal.c (stop_numeric): Reimplement.

>             (stop_string, error_stop_string, error_stop_numeric): New

>             functions.

>             libgomp/

>             PR libgomp/85463

>             * testsuite/libgomp.oacc-fortran/error_stop-1.f: New file.

>             * testsuite/libgomp.oacc-fortran/error_stop-2.f: Likewise.

>             * testsuite/libgomp.oacc-fortran/error_stop-3.f: Likewise.

>             * testsuite/libgomp.oacc-fortran/stop-1.f: Likewise.

>             * testsuite/libgomp.oacc-fortran/stop-2.f: Likewise.

>             * testsuite/libgomp.oacc-fortran/stop-3.f: Likewise.

>     


The "output pattern test" part of all of these new testcases fail on my
HSA tester even though no HSAIL is generated for them, only host
fallback is used.  Looking at the first one:

> diff --git libgomp/testsuite/libgomp.oacc-fortran/error_stop-1.f libgomp/testsuite/libgomp.oacc-fortran/error_stop-1.f

> new file mode 100644

> index 0000000..4965e67

> --- /dev/null

> +++ libgomp/testsuite/libgomp.oacc-fortran/error_stop-1.f

> @@ -0,0 +1,20 @@

> +! { dg-do run }

> +

> +      PROGRAM MAIN

> +      IMPLICIT NONE

> +

> +      PRINT *, "CheCKpOInT"

> +!$ACC PARALLEL

> +      ERROR STOP

> +!$ACC END PARALLEL

> +      PRINT *, "WrONg WAy"

> +

> +      END PROGRAM MAIN

> +

> +! { dg-output "CheCKpOInT(\n|\r\n|\r)+" }

> +! { dg-output "ERROR STOP (\n|\r\n|\r)+" }

> +! PR85463.  The "minimal" libgfortran implementation used with nvptx

> +! offloading is a little bit different.

> +! { dg-output "Error termination.*" { target { ! openacc_nvidia_accel_selected } } }

> +! { dg-output "libgomp: cuStreamSynchronize error.*" { target openacc_nvidia_accel_selected } }

> +! { dg-shouldfail "" }


I can tell that checking for "CheCKpOInT" passes but checking for "ERROR
STOP" and "Error termination" do not.  Running the test manually, they
both appear, but in standard error, not standard output (where
CheCKpOInT is printed).  I am not 100% sure whether that is the reason
why they fail but do we have a way of testing std error of the executed
compiled binary?

Thanks,

Martin
Thomas Schwinge April 26, 2018, 10:47 a.m. | #9
Hi Martin!

On Wed, 25 Apr 2018 15:56:26 +0200, Martin Jambor <mjambor@suse.cz> wrote:
> On Thu, Apr 19 2018, Thomas Schwinge wrote:

> >             * testsuite/libgomp.oacc-fortran/error_stop-1.f: New file.

> >             * testsuite/libgomp.oacc-fortran/error_stop-2.f: Likewise.

> >             * testsuite/libgomp.oacc-fortran/error_stop-3.f: Likewise.

> >             * testsuite/libgomp.oacc-fortran/stop-1.f: Likewise.

> >             * testsuite/libgomp.oacc-fortran/stop-2.f: Likewise.

> >             * testsuite/libgomp.oacc-fortran/stop-3.f: Likewise.

> 

> The "output pattern test" part of all of these new testcases fail on my

> HSA tester even though no HSAIL is generated for them


(Right, that's expected: there's currently no HSA/HSAIL support for
OpenACC constructs.)

> only host

> fallback is used.


So that's essentially the configuration that a lot of people use: libgomp
testing with no offloading configured; host fallback only.

> Looking at the first one:

> 

> > diff --git libgomp/testsuite/libgomp.oacc-fortran/error_stop-1.f libgomp/testsuite/libgomp.oacc-fortran/error_stop-1.f

> > new file mode 100644

> > index 0000000..4965e67

> > --- /dev/null

> > +++ libgomp/testsuite/libgomp.oacc-fortran/error_stop-1.f

> > @@ -0,0 +1,20 @@

> > +! { dg-do run }

> > +

> > +      PROGRAM MAIN

> > +      IMPLICIT NONE

> > +

> > +      PRINT *, "CheCKpOInT"

> > +!$ACC PARALLEL

> > +      ERROR STOP

> > +!$ACC END PARALLEL

> > +      PRINT *, "WrONg WAy"

> > +

> > +      END PROGRAM MAIN

> > +

> > +! { dg-output "CheCKpOInT(\n|\r\n|\r)+" }

> > +! { dg-output "ERROR STOP (\n|\r\n|\r)+" }

> > +! PR85463.  The "minimal" libgfortran implementation used with nvptx

> > +! offloading is a little bit different.

> > +! { dg-output "Error termination.*" { target { ! openacc_nvidia_accel_selected } } }

> > +! { dg-output "libgomp: cuStreamSynchronize error.*" { target openacc_nvidia_accel_selected } }

> > +! { dg-shouldfail "" }

> 

> I can tell that checking for "CheCKpOInT" passes but checking for "ERROR

> STOP" and "Error termination" do not.  Running the test manually, they

> both appear, but in standard error, not standard output (where

> CheCKpOInT is printed).


ACK (stdout, then stderr).  Though, as there are no "FAIL" reports so far
(including posts on the gcc-regression and gcc-testresults mailing
lists), I'm assuming that stdout/stderr do synchronize in order here, as
expected.  (As far as I remember, the Fortran PRINT does flush stdout.)

> I am not 100% sure whether that is the reason

> why they fail but do we have a way of testing std error of the executed

> compiled binary?


Is there anything "special" in your HSA machine regarding stdout/stderr?
How are you testing GCC there: native testing or some non-standard *.exp
file, for example?  Does using strace give any idea where which part of
the output is going?


Grüße
 Thomas
Martin Jambor April 26, 2018, 12:38 p.m. | #10
Hi,

On Thu, Apr 26 2018, Thomas Schwinge wrote:
> Hi Martin!

>

> On Wed, 25 Apr 2018 15:56:26 +0200, Martin Jambor <mjambor@suse.cz> wrote:

>> On Thu, Apr 19 2018, Thomas Schwinge wrote:

>> >             * testsuite/libgomp.oacc-fortran/error_stop-1.f: New file.

>> >             * testsuite/libgomp.oacc-fortran/error_stop-2.f: Likewise.

>> >             * testsuite/libgomp.oacc-fortran/error_stop-3.f: Likewise.

>> >             * testsuite/libgomp.oacc-fortran/stop-1.f: Likewise.

>> >             * testsuite/libgomp.oacc-fortran/stop-2.f: Likewise.

>> >             * testsuite/libgomp.oacc-fortran/stop-3.f: Likewise.

>> 

>> The "output pattern test" part of all of these new testcases fail on my

>> HSA tester even though no HSAIL is generated for them

>

>

> Is there anything "special" in your HSA machine regarding stdout/stderr?

> How are you testing GCC there: native testing or some non-standard *.exp

> file, for example?  Does using strace give any idea where which part of

> the output is going?

>


this issue was caused on my side, because the ROCm runtime produced some
debug output to stderr upon initialization.  I have backported a fix for
this to my packages and the issues is gone.

It is still slightly intriguing, because the patterns dg-output was
searching for were present there also before, the debug stuff did not
appear in the middle of them or anything, so I do not quite understand
why the tests were failing before, but it is probably not worth
investigating.  Let's hope the periodic run next week will agree with my
manual tests.

Sorry for the noise,

Martin

Patch

diff --git libgfortran/ChangeLog libgfortran/ChangeLog
index d4a1fbb..ea4358c 100644
--- libgfortran/ChangeLog
+++ libgfortran/ChangeLog
@@ -1,3 +1,11 @@ 
+2018-04-19  Thomas Schwinge  <thomas@codesourcery.com>
+
+	PR libfortran/85166
+	PR libgomp/85463
+	* runtime/minimal.c (stop_numeric): Reimplement.
+	(stop_string, error_stop_string, error_stop_numeric): New
+	functions.
+
 2018-04-19  Jakub Jelinek  <jakub@redhat.com>
 
 	* configure: Regenerated.
diff --git libgfortran/runtime/minimal.c libgfortran/runtime/minimal.c
index e17666b..0b1efeb 100644
--- libgfortran/runtime/minimal.c
+++ libgfortran/runtime/minimal.c
@@ -188,6 +188,22 @@  sys_abort (void)
   abort();
 }
 
+
+/* runtime/stop.c */
+
+#undef report_exception
+#define report_exception() do {} while (0)
+#undef st_printf
+#define st_printf printf
+#undef estr_write
+#define estr_write printf
+/* Map "exit" to "abort"; see PR85463 '[nvptx] "exit" in offloaded region
+   doesn't terminate process'.  */
+#undef exit
+#define exit(...) do { abort (); } while (0)
+#undef exit_error
+#define exit_error(...) do { abort (); } while (0)
+
 /* A numeric STOP statement.  */
 
 extern _Noreturn void stop_numeric (int, bool);
@@ -197,7 +213,67 @@  void
 stop_numeric (int code, bool quiet)
 {
   if (!quiet)
-    printf ("STOP %d\n", code);
-
+    {
+      report_exception ();
+      st_printf ("STOP %d\n", code);
+    }
   exit (code);
 }
+
+
+/* A character string or blank STOP statement.  */
+
+void
+stop_string (const char *string, size_t len, bool quiet)
+{
+  if (!quiet)
+    {
+      report_exception ();
+      if (string)
+	{
+	  estr_write ("STOP ");
+	  (void) write (STDERR_FILENO, string, len);
+	  estr_write ("\n");
+	}
+    }
+  exit (0);
+}
+
+
+/* Per Fortran 2008, section 8.4:  "Execution of a STOP statement initiates
+   normal termination of execution. Execution of an ERROR STOP statement
+   initiates error termination of execution."  Thus, error_stop_string returns
+   a nonzero exit status code.  */
+
+extern _Noreturn void error_stop_string (const char *, size_t, bool);
+export_proto(error_stop_string);
+
+void
+error_stop_string (const char *string, size_t len, bool quiet)
+{
+  if (!quiet)
+    {
+      report_exception ();
+      estr_write ("ERROR STOP ");
+      (void) write (STDERR_FILENO, string, len);
+      estr_write ("\n");
+    }
+  exit_error (1);
+}
+
+
+/* A numeric ERROR STOP statement.  */
+
+extern _Noreturn void error_stop_numeric (int, bool);
+export_proto(error_stop_numeric);
+
+void
+error_stop_numeric (int code, bool quiet)
+{
+  if (!quiet)
+    {
+      report_exception ();
+      st_printf ("ERROR STOP %d\n", code);
+    }
+  exit_error (code);
+}
diff --git libgomp/ChangeLog libgomp/ChangeLog
index 1025acb..f68a4a8 100644
--- libgomp/ChangeLog
+++ libgomp/ChangeLog
@@ -1,3 +1,18 @@ 
+2018-04-19  Thomas Schwinge  <thomas@codesourcery.com>
+
+	PR libgomp/85463
+	* testsuite/libgomp.oacc-fortran/error_stop-1.f: New file.
+	* testsuite/libgomp.oacc-fortran/error_stop-2.f: Likewise.
+	* testsuite/libgomp.oacc-fortran/error_stop-3.f: Likewise.
+	* testsuite/libgomp.oacc-fortran/stop-1.f: Likewise.
+	* testsuite/libgomp.oacc-fortran/stop-2.f: Likewise.
+	* testsuite/libgomp.oacc-fortran/stop-3.f: Likewise.
+
+	PR libfortran/85166
+	* testsuite/libgomp.oacc-fortran/abort-1.f90: Switch back to "call
+	abort".
+	* testsuite/libgomp.oacc-fortran/abort-2.f90: Likewise.
+
 2018-04-19  Jakub Jelinek  <jakub@redhat.com>
 
 	* configure: Regenerated.
diff --git libgomp/testsuite/libgomp.oacc-fortran/abort-1.f90 libgomp/testsuite/libgomp.oacc-fortran/abort-1.f90
index dde3512..fc0af7f 100644
--- libgomp/testsuite/libgomp.oacc-fortran/abort-1.f90
+++ libgomp/testsuite/libgomp.oacc-fortran/abort-1.f90
@@ -1,9 +1,12 @@ 
+! Verify that an unconditional "call abort" inside an OpenACC parallel region
+! does the right thing.
+
 program main
   implicit none
 
   print *, "CheCKpOInT"
   !$acc parallel
-  STOP 1
+  call abort
   !$acc end parallel
 
 end program main
diff --git libgomp/testsuite/libgomp.oacc-fortran/abort-2.f90 libgomp/testsuite/libgomp.oacc-fortran/abort-2.f90
index 68d90e9..97a692b 100644
--- libgomp/testsuite/libgomp.oacc-fortran/abort-2.f90
+++ libgomp/testsuite/libgomp.oacc-fortran/abort-2.f90
@@ -1,3 +1,6 @@ 
+! Verify that a conditional "call abort" inside an OpenACC parallel region does
+! the right thing.
+
 program main
   implicit none
 
@@ -6,7 +9,7 @@  program main
 
   !$acc parallel copyin(argc)
   if (argc .ne. 0) then
-     STOP 1
+     call abort
   end if
   !$acc end parallel
 
diff --git libgomp/testsuite/libgomp.oacc-fortran/error_stop-1.f libgomp/testsuite/libgomp.oacc-fortran/error_stop-1.f
new file mode 100644
index 0000000..4965e67
--- /dev/null
+++ libgomp/testsuite/libgomp.oacc-fortran/error_stop-1.f
@@ -0,0 +1,20 @@ 
+! { dg-do run }
+
+      PROGRAM MAIN
+      IMPLICIT NONE
+
+      PRINT *, "CheCKpOInT"
+!$ACC PARALLEL
+      ERROR STOP
+!$ACC END PARALLEL
+      PRINT *, "WrONg WAy"
+
+      END PROGRAM MAIN
+
+! { dg-output "CheCKpOInT(\n|\r\n|\r)+" }
+! { dg-output "ERROR STOP (\n|\r\n|\r)+" }
+! PR85463.  The "minimal" libgfortran implementation used with nvptx
+! offloading is a little bit different.
+! { dg-output "Error termination.*" { target { ! openacc_nvidia_accel_selected } } }
+! { dg-output "libgomp: cuStreamSynchronize error.*" { target openacc_nvidia_accel_selected } }
+! { dg-shouldfail "" }
diff --git libgomp/testsuite/libgomp.oacc-fortran/error_stop-2.f libgomp/testsuite/libgomp.oacc-fortran/error_stop-2.f
new file mode 100644
index 0000000..7103fdb
--- /dev/null
+++ libgomp/testsuite/libgomp.oacc-fortran/error_stop-2.f
@@ -0,0 +1,20 @@ 
+! { dg-do run }
+
+      PROGRAM MAIN
+      IMPLICIT NONE
+
+      PRINT *, "CheCKpOInT"
+!$ACC PARALLEL
+      ERROR STOP 35
+!$ACC END PARALLEL
+      PRINT *, "WrONg WAy"
+
+      END PROGRAM MAIN
+
+! { dg-output "CheCKpOInT(\n|\r\n|\r)+" }
+! { dg-output "ERROR STOP 35(\n|\r\n|\r)+" }
+! PR85463.  The "minimal" libgfortran implementation used with nvptx
+! offloading is a little bit different.
+! { dg-output "Error termination.*" { target { ! openacc_nvidia_accel_selected } } }
+! { dg-output "libgomp: cuStreamSynchronize error.*" { target openacc_nvidia_accel_selected } }
+! { dg-shouldfail "" }
diff --git libgomp/testsuite/libgomp.oacc-fortran/error_stop-3.f libgomp/testsuite/libgomp.oacc-fortran/error_stop-3.f
new file mode 100644
index 0000000..9c217f1
--- /dev/null
+++ libgomp/testsuite/libgomp.oacc-fortran/error_stop-3.f
@@ -0,0 +1,20 @@ 
+! { dg-do run }
+
+      PROGRAM MAIN
+      IMPLICIT NONE
+
+      PRINT *, "CheCKpOInT"
+!$ACC PARALLEL
+      ERROR STOP "SiGN"
+!$ACC END PARALLEL
+      PRINT *, "WrONg WAy"
+
+      END PROGRAM MAIN
+
+! { dg-output "CheCKpOInT(\n|\r\n|\r)+" }
+! { dg-output "ERROR STOP SiGN(\n|\r\n|\r)+" }
+! PR85463.  The "minimal" libgfortran implementation used with nvptx
+! offloading is a little bit different.
+! { dg-output "Error termination.*" { target { ! openacc_nvidia_accel_selected } } }
+! { dg-output "libgomp: cuStreamSynchronize error.*" { target openacc_nvidia_accel_selected } }
+! { dg-shouldfail "" }
diff --git libgomp/testsuite/libgomp.oacc-fortran/stop-1.f libgomp/testsuite/libgomp.oacc-fortran/stop-1.f
new file mode 100644
index 0000000..af267fc
--- /dev/null
+++ libgomp/testsuite/libgomp.oacc-fortran/stop-1.f
@@ -0,0 +1,22 @@ 
+! { dg-do run }
+
+      PROGRAM MAIN
+      IMPLICIT NONE
+
+      PRINT *, "CheCKpOInT"
+!$ACC PARALLEL
+      STOP
+!$ACC END PARALLEL
+      PRINT *, "WrONg WAy"
+
+      END PROGRAM MAIN
+
+! { dg-output "CheCKpOInT(\n|\r\n|\r)+" }
+! PR85463.  The "minimal" libgfortran implementation used with nvptx
+! offloading is a little bit different.
+! { dg-output "libgomp: cuStreamSynchronize error.*" { target openacc_nvidia_accel_selected } }
+! { dg-output "$" }
+! PR85463.  STOP with code zero (as implied here) should actually
+! terminate the process normally, but doesn't in the "minimal"
+! libgfortran implementation used with nvptx offloading.
+! { dg-shouldfail "" { openacc_nvidia_accel_selected } }
diff --git libgomp/testsuite/libgomp.oacc-fortran/stop-2.f libgomp/testsuite/libgomp.oacc-fortran/stop-2.f
new file mode 100644
index 0000000..13c0684
--- /dev/null
+++ libgomp/testsuite/libgomp.oacc-fortran/stop-2.f
@@ -0,0 +1,20 @@ 
+! { dg-do run }
+
+      PROGRAM MAIN
+      IMPLICIT NONE
+
+      PRINT *, "CheCKpOInT"
+!$ACC PARALLEL
+      STOP 35
+!$ACC END PARALLEL
+      PRINT *, "WrONg WAy"
+
+      END PROGRAM MAIN
+
+! { dg-output "CheCKpOInT(\n|\r\n|\r)+" }
+! { dg-output "STOP 35(\n|\r\n|\r)+" }
+! PR85463.  The "minimal" libgfortran implementation used with nvptx
+! offloading is a little bit different.
+! { dg-output "libgomp: cuStreamSynchronize error.*" { target openacc_nvidia_accel_selected } }
+! { dg-output "$" }
+! { dg-shouldfail "" }
diff --git libgomp/testsuite/libgomp.oacc-fortran/stop-3.f libgomp/testsuite/libgomp.oacc-fortran/stop-3.f
new file mode 100644
index 0000000..3bd7446
--- /dev/null
+++ libgomp/testsuite/libgomp.oacc-fortran/stop-3.f
@@ -0,0 +1,23 @@ 
+! { dg-do run }
+
+      PROGRAM MAIN
+      IMPLICIT NONE
+
+      PRINT *, "CheCKpOInT"
+!$ACC PARALLEL
+      STOP "SiGN"
+!$ACC END PARALLEL
+      PRINT *, "WrONg WAy"
+
+      END PROGRAM MAIN
+
+! { dg-output "CheCKpOInT(\n|\r\n|\r)+" }
+! { dg-output "STOP SiGN(\n|\r\n|\r)+" }
+! PR85463.  The "minimal" libgfortran implementation used with nvptx
+! offloading is a little bit different.
+! { dg-output "libgomp: cuStreamSynchronize error.*" { target openacc_nvidia_accel_selected } }
+! { dg-output "$" }
+! PR85463.  STOP with code zero (as implied here) should actually
+! terminate the process normally, but doesn't in the "minimal"
+! libgfortran implementation used with nvptx offloading.
+! { dg-shouldfail "" { openacc_nvidia_accel_selected } }