This is about a PARAM_DECL of a procedure whose internal/nested procedure uses this inside an omp parallel. This leads to the code:
D.3940 = x; (*D.3940)[D.3924] = …; And the temporary variable "D.3940" introduced for the nesting was not recorded as DECL for OpenMP, leading to the ICE in scan_omp_1_op as shown in the ICE. This patch adds those temporary variables as PRIVATE to the clause – fixing the ICE. OK for the trunk? Tobias PS: For other other variables, that's done with gimplify.c which adds it to the splay_tree, hence, this issue only occurs if the variable is added later – as here for tree-nested.c. The new code is also used for some C OpenMP/OpenACC testcases in the testsuite, but seemingly it works either way. Interestingly, I do not see any 'private' in the dump for the new testcase – seemingly, it gets optimized away. PPS: Thanks for Jakub for some suggestions! ----------------- Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander Walter
OpenMP: Fix tmp-var handling with tree-nested.c [PR93553] gcc/ChangeLog: PR fortran/93553 * tree-nested.c (omp_new_clauses): New global var. (convert_nonlocal_reference_op): Add init_tmp_var/init_tmp_var vars to it. (convert_nonlocal_omp_clauses, convert_local_omp_clauses): Add those as 'private' to the OpenMP clause. libgomp/ChangeLog: PR fortran/93553 * testsuite/libgomp.fortran/pr93553.f90: New test. gcc/tree-nested.c | 37 +++++++++++++++++++++++++-- libgomp/testsuite/libgomp.fortran/pr93553.f90 | 21 +++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c index 4dc5533be84..8c4dadc9f21 100644 --- a/gcc/tree-nested.c +++ b/gcc/tree-nested.c @@ -111,6 +111,7 @@ struct nesting_info char static_chain_added; }; +static tree omp_new_clauses; /* Iterate over the nesting tree, starting with ROOT, depth first. */ @@ -1068,6 +1069,11 @@ convert_nonlocal_reference_op (tree *tp, int *walk_subtrees, void *data) if (use_pointer_in_frame (t)) { x = init_tmp_var (info, x, &wi->gsi); + tree c = build_omp_clause (DECL_SOURCE_LOCATION (x), + OMP_CLAUSE_PRIVATE); + OMP_CLAUSE_DECL (c) = x; + OMP_CLAUSE_CHAIN (c) = omp_new_clauses; + omp_new_clauses = c; x = build_simple_mem_ref_notrap (x); } } @@ -1078,6 +1084,11 @@ convert_nonlocal_reference_op (tree *tp, int *walk_subtrees, void *data) x = save_tmp_var (info, x, &wi->gsi); else x = init_tmp_var (info, x, &wi->gsi); + tree c = build_omp_clause (DECL_SOURCE_LOCATION (x), + OMP_CLAUSE_PRIVATE); + OMP_CLAUSE_DECL (c) = x; + OMP_CLAUSE_CHAIN (c) = omp_new_clauses; + omp_new_clauses = c; } *tp = x; @@ -1186,15 +1197,18 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) { struct nesting_info *const info = (struct nesting_info *) wi->info; bool need_chain = false, need_stmts = false; - tree clause, decl, *pdecl; + tree clause, last_clause, decl, *pdecl; int dummy; bitmap new_suppress; + tree saved_omp_new_clauses = omp_new_clauses; + omp_new_clauses = NULL_TREE; new_suppress = BITMAP_GGC_ALLOC (); bitmap_copy (new_suppress, info->suppress_expansion); for (clause = *pclauses; clause ; clause = OMP_CLAUSE_CHAIN (clause)) { + last_clause = clause; pdecl = NULL; switch (OMP_CLAUSE_CODE (clause)) { @@ -1450,6 +1464,14 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) break; } + + if (omp_new_clauses) + { + gcc_assert (*pclauses); + OMP_CLAUSE_CHAIN (last_clause) = omp_new_clauses; + } + omp_new_clauses = saved_omp_new_clauses; + return need_chain; } @@ -1919,15 +1941,19 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) { struct nesting_info *const info = (struct nesting_info *) wi->info; bool need_frame = false, need_stmts = false; - tree clause, decl, *pdecl; + tree clause, last_clause, decl, *pdecl; int dummy; bitmap new_suppress; + tree saved_omp_new_clauses = omp_new_clauses; + omp_new_clauses = NULL_TREE; + new_suppress = BITMAP_GGC_ALLOC (); bitmap_copy (new_suppress, info->suppress_expansion); for (clause = *pclauses; clause ; clause = OMP_CLAUSE_CHAIN (clause)) { + last_clause = clause; pdecl = NULL; switch (OMP_CLAUSE_CODE (clause)) { @@ -2193,6 +2219,13 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) break; } + if (omp_new_clauses) + { + gcc_assert (*pclauses); + OMP_CLAUSE_CHAIN (last_clause) = omp_new_clauses; + } + omp_new_clauses = saved_omp_new_clauses; + return need_frame; } diff --git a/libgomp/testsuite/libgomp.fortran/pr93553.f90 b/libgomp/testsuite/libgomp.fortran/pr93553.f90 new file mode 100644 index 00000000000..5d6f10febed --- /dev/null +++ b/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