[nvptx,PR84028] Add exit insn after noreturn call for neutered workers

Message ID afbfa574-228a-d1b0-89d2-8eef1c848417@mentor.com
State New
Headers show
Series
  • [nvptx,PR84028] Add exit insn after noreturn call for neutered workers
Related show

Commit Message

Tom de Vries Jan. 25, 2018, 10:38 a.m.
Hi,

[ Note: this is similar to "[nvptx, PR81352] Add exit insn after 
noreturn call for neutered threads in warp" 
https://gcc.gnu.org/ml/gcc-patches/2018-01/msg02013.html ].

atm the test-case contained in this patch hangs at -O1 and higher.

For the test-case we generate:
...
$L4:
   @ %r56 bra.uni $L27;
   @ %r57 bra $L28;
   {
     call _gfortran_abort;
     trap;
     exit;
   }
$L28:
   exit;
$L27:
...

The problem is that the neutered worker takes the branch to $L27, and 
executes random code afterwards.

The fix is to add an exit insn after the worker neutering join, as we 
did for the vector neutering join (which we can see here after $L28).

Build and reg-tested on x86_64 with nvptx accelerator.

Committed in stage4 as non-intrusive wrong-code fix.

Thanks,
- Tom

Patch

[nvptx, PR84028] Add exit insn after noreturn call for neutered workers

2018-01-25  Tom de Vries  <tom@codesourcery.com>

	PR target/84028
	* config/nvptx/nvptx.c (nvptx_single): Add exit insn after noreturn call
	for neutered workers.

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

---
 gcc/config/nvptx/nvptx.c                           |  4 ++--
 libgomp/testsuite/libgomp.oacc-fortran/pr84028.f90 | 25 ++++++++++++++++++++++
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/gcc/config/nvptx/nvptx.c b/gcc/config/nvptx/nvptx.c
index d848412..a6f4443 100644
--- a/gcc/config/nvptx/nvptx.c
+++ b/gcc/config/nvptx/nvptx.c
@@ -4065,8 +4065,8 @@  nvptx_single (unsigned mask, basic_block from, basic_block to)
 	else
 	  {
 	    rtx_insn *label_insn = emit_label_after (label, tail);
-	    if (mode == GOMP_DIM_VECTOR && CALL_P (tail)
-		&& find_reg_note (tail, REG_NORETURN, NULL))
+	    if ((mode == GOMP_DIM_VECTOR || mode == GOMP_DIM_WORKER)
+		&& CALL_P (tail) && find_reg_note (tail, REG_NORETURN, NULL))
 	      emit_insn_after (gen_exit (), label_insn);
 	  }
       }
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/pr84028.f90 b/libgomp/testsuite/libgomp.oacc-fortran/pr84028.f90
new file mode 100644
index 0000000..ed6e326
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/pr84028.f90
@@ -0,0 +1,25 @@ 
+! { dg-do run }
+
+program foo
+  integer :: a(3,3,3), ll, lll
+
+  a = 1
+
+  !$acc parallel num_gangs(1) num_workers(2)
+
+  if (any(a(1:3,1:3,1:3).ne.1)) call abort
+
+  do ll=1,3
+
+     !$acc loop vector
+     do lll=1,3
+        a(1,ll,lll) = 2
+     enddo
+
+  enddo
+
+  if (a(1,1,1).ne.2) call abort
+
+  !$acc end parallel
+
+end program foo