diff mbox series

[committed] openmp: Handle clauses with gimple sequences in convert_nonlocal_omp_clauses properly [PR93553]

Message ID 20200808091716.GH2363@tucnak
State New
Headers show
Series [committed] openmp: Handle clauses with gimple sequences in convert_nonlocal_omp_clauses properly [PR93553] | expand

Commit Message

Jakub Jelinek Aug. 8, 2020, 9:17 a.m. UTC
Hi!

On Mon, Aug 03, 2020 at 07:44:12PM +0200, Jakub Jelinek via Gcc-patches wrote:
> Can you try that?  Or do you want me to try?

If the walk_body on the various sequences of reduction, lastprivate and/or linear
clauses needs to create a temporary variable, we should declare that variable
in that sequence rather than outside, where it would need to be privatized inside of
the construct.

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

Didn't handle convert_local_omp_clauses yet, guess it would be best to have
a testcase first and I didn't get to write it so far.

2020-08-08  Jakub Jelinek  <jakub@redhat.com>

	PR fortran/93553
	* tree-nested.c (convert_nonlocal_omp_clauses): For
	OMP_CLAUSE_REDUCTION, OMP_CLAUSE_LASTPRIVATE and OMP_CLAUSE_LINEAR
	save info->new_local_var_chain around walks of the clause gimple
	sequences and declare_vars if needed into the sequence.

2020-08-08  Tobias Burnus  <tobias@codesourcery.com>

	PR fortran/93553
	* testsuite/libgomp.fortran/pr93553.f90: New test.


	Jakub
diff mbox series

Patch

--- gcc/tree-nested.c.jj	2020-08-03 22:54:51.438531379 +0200
+++ gcc/tree-nested.c	2020-08-07 19:30:58.671402609 +0200
@@ -1419,12 +1419,22 @@  convert_nonlocal_omp_clauses (tree *pcla
 	      if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clause))
 		DECL_CONTEXT (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clause))
 		  = info->context;
+	      tree save_local_var_chain = info->new_local_var_chain;
+	      info->new_local_var_chain = NULL;
+	      gimple_seq *seq = &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (clause);
 	      walk_body (convert_nonlocal_reference_stmt,
-			 convert_nonlocal_reference_op, info,
-			 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (clause));
+			 convert_nonlocal_reference_op, info, seq);
+	      if (info->new_local_var_chain)
+		declare_vars (info->new_local_var_chain,
+			      gimple_seq_first_stmt (*seq), false);
+	      info->new_local_var_chain = NULL;
+	      seq = &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (clause);
 	      walk_body (convert_nonlocal_reference_stmt,
-			 convert_nonlocal_reference_op, info,
-			 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (clause));
+			 convert_nonlocal_reference_op, info, seq);
+	      if (info->new_local_var_chain)
+		declare_vars (info->new_local_var_chain,
+			      gimple_seq_first_stmt (*seq), false);
+	      info->new_local_var_chain = save_local_var_chain;
 	      DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
 		= old_context;
 	      if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clause))
@@ -1434,15 +1444,31 @@  convert_nonlocal_omp_clauses (tree *pcla
 	  break;
 
 	case OMP_CLAUSE_LASTPRIVATE:
-	  walk_body (convert_nonlocal_reference_stmt,
-		     convert_nonlocal_reference_op, info,
-		     &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause));
+	  {
+	    tree save_local_var_chain = info->new_local_var_chain;
+	    info->new_local_var_chain = NULL;
+	    gimple_seq *seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause);
+	    walk_body (convert_nonlocal_reference_stmt,
+		       convert_nonlocal_reference_op, info, seq);
+	    if (info->new_local_var_chain)
+	      declare_vars (info->new_local_var_chain,
+			    gimple_seq_first_stmt (*seq), false);
+	    info->new_local_var_chain = save_local_var_chain;
+	  }
 	  break;
 
 	case OMP_CLAUSE_LINEAR:
-	  walk_body (convert_nonlocal_reference_stmt,
-		     convert_nonlocal_reference_op, info,
-		     &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (clause));
+	  {
+	    tree save_local_var_chain = info->new_local_var_chain;
+	    info->new_local_var_chain = NULL;
+	    gimple_seq *seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (clause);
+	    walk_body (convert_nonlocal_reference_stmt,
+		       convert_nonlocal_reference_op, info, seq);
+	    if (info->new_local_var_chain)
+	      declare_vars (info->new_local_var_chain,
+			    gimple_seq_first_stmt (*seq), false);
+	    info->new_local_var_chain = save_local_var_chain;
+	  }
 	  break;
 
 	default:
--- libgomp/testsuite/libgomp.fortran/pr93553.f90
+++ libgomp/testsuite/libgomp.fortran/pr93553.f90
@@ -0,0 +1,21 @@ 
+program p
+   implicit none
+   integer :: x(8) = 0
+   call sub(x)
+end
+subroutine sub(x)
+   implicit none
+   integer i
+   integer :: x(8)
+   integer :: c(8) = [(11*i, i=1,8)]
+   call s
+   if (any (x /= c)) stop 1
+contains
+   subroutine s
+      integer :: i
+      !$omp parallel do reduction(+:x)
+      do i = 1, 8
+         x(i) = c(i)
+      end do
+   end
+end