Fix inner loop phi in expand_omp_for_static_chunk 2015-08-31 Tom de Vries PR tree-optimization/65637 * omp-low.c (find_phi_with_arg_on_edge): New function. (expand_omp_for_static_chunk): Fix inner loop phi. * testsuite/libgomp.c/autopar-1-chunk-size.c: New test. --- gcc/ChangeLog | 6 +++ gcc/omp-low.c | 30 ++++++++++++++- libgomp/testsuite/libgomp.c/autopar-1-chunk-size.c | 44 ++++++++++++++++++++++ 3 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 libgomp/testsuite/libgomp.c/autopar-1-chunk-size.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5a273ba..a14564c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,12 @@ 2015-05-18 Tom de Vries PR tree-optimization/65637 + * omp-low.c (find_phi_with_arg_on_edge): New function. + (expand_omp_for_static_chunk): Fix inner loop phi. + +2015-05-18 Tom de Vries + + PR tree-optimization/65637 * omp-low.c (expand_omp_for_static_chunk): Fix gcc_assert for the case that head is NULL. diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 4e732ae..e2be7c7 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -6885,6 +6885,22 @@ expand_omp_for_static_nochunk (struct omp_region *region, } } +static gphi * +find_phi_with_arg_on_edge (tree arg, edge e) +{ + basic_block bb = e->dest; + + for (gphi_iterator gpi = gsi_start_phis (bb); + !gsi_end_p (gpi); + gsi_next (&gpi)) + { + gphi *phi = gpi.phi (); + if (PHI_ARG_DEF_FROM_EDGE (phi, e) == arg) + return phi; + } + + return NULL; +} /* A subroutine of expand_omp_for. Generate code for a parallel loop with static schedule and a specified chunk size. Given @@ -7324,7 +7340,19 @@ expand_omp_for_static_chunk (struct omp_region *region, t = vextra; add_phi_arg (nphi, t, ene, locus); locus = redirect_edge_var_map_location (vm); - add_phi_arg (nphi, redirect_edge_var_map_def (vm), re, locus); + tree back_arg = redirect_edge_var_map_def (vm); + add_phi_arg (nphi, back_arg, re, locus); + edge ce = find_edge (cont_bb, body_bb); + if (ce == NULL) + { + ce = BRANCH_EDGE (cont_bb); + gcc_assert (single_succ (ce->dest) == body_bb); + ce = single_succ_edge (ce->dest); + } + gphi *inner_loop_phi = find_phi_with_arg_on_edge (back_arg, ce); + gcc_assert (inner_loop_phi != NULL); + add_phi_arg (inner_loop_phi, gimple_phi_result (nphi), + find_edge (seq_start_bb, body_bb), locus); } gcc_assert (gsi_end_p (psi) && (head == NULL || i == head->length ())); redirect_edge_var_map_clear (re); diff --git a/libgomp/testsuite/libgomp.c/autopar-1-chunk-size.c b/libgomp/testsuite/libgomp.c/autopar-1-chunk-size.c new file mode 100644 index 0000000..5a36474 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/autopar-1-chunk-size.c @@ -0,0 +1,44 @@ +/* { dg-do run } */ +/* { dg-additional-options "-ftree-parallelize-loops=4 -ffast-math --param parloops-chunk-size=100" } */ + +extern void abort (void); + +double d[1024], e[1024]; +int f[1024], g[1024]; + +double __attribute__((noinline)) +foo (void) +{ + double s = 0.0; + int i; + for (i = 0; i < 1024; i++) + s += d[i] - e[i]; + return s; +} + +int __attribute__((noinline)) +bar (void) +{ + int s = 0, i; + for (i = 0; i < 1024; i++) + s += f[i] - g[i]; + return s; +} + +int +main (void) +{ + int i; + for (i = 0; i < 1024; i++) + { + d[i] = i * 2; + e[i] = i; + f[i] = i * 2; + g[i] = i; + } + if (foo () != 1023 * 1024 / 2) + abort (); + if (bar () != 1023 * 1024 / 2) + abort (); + return 0; +} -- 1.9.1