From b81f2dafdbd2c5aa49213b35dc12d4610834e39e Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 30 Oct 2019 13:52:27 +0000 Subject: [PATCH] re PR tree-optimization/92275 (ICE: error: definition in block 11 does not dominate use in block 15 since r277566) 2019-10-30 Richard Biener PR tree-optimization/92275 * tree-vect-loop-manip.c (slpeel_update_phi_nodes_for_loops): Copy all loop-closed PHIs. * gcc.dg/torture/pr92275.c: New testcase. From-SVN: r277621 --- gcc/ChangeLog | 6 +++ gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.dg/torture/pr92275.c | 13 +++++ gcc/tree-vect-loop-manip.c | 69 +++++++++++++++++--------- 4 files changed, 70 insertions(+), 23 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr92275.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index eac83494c5f..40e2c3ff938 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-10-30 Richard Biener + + PR tree-optimization/92275 + * tree-vect-loop-manip.c (slpeel_update_phi_nodes_for_loops): + Copy all loop-closed PHIs. + 2019-10-30 Martin Liska * ipa-icf-gimple.c (func_checker::compare_ssa_name): Use diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d4cf73c100a..10cf9415292 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-10-30 Richard Biener + + PR tree-optimization/92275 + * gcc.dg/torture/pr92275.c: New testcase. + 2019-10-30 Jakub Jelinek * g++.dg/gomp/declare-variant-6.C: New test. diff --git a/gcc/testsuite/gcc.dg/torture/pr92275.c b/gcc/testsuite/gcc.dg/torture/pr92275.c new file mode 100644 index 00000000000..b9f70889758 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr92275.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-ftree-vectorize" } */ + +unsigned long a, c; +int *b, *b2; +long d; + +void fn1() +{ + for (; b < b2; b++) + d += *b * c; + d *= a; +} diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c index dffb40ec999..1fbcaf2676f 100644 --- a/gcc/tree-vect-loop-manip.c +++ b/gcc/tree-vect-loop-manip.c @@ -2004,6 +2004,29 @@ vect_gen_vector_loop_niters_mult_vf (loop_vec_info loop_vinfo, *niters_vector_mult_vf_ptr = niters_vector_mult_vf; } +/* LCSSA_PHI is a lcssa phi of EPILOG loop which is copied from LOOP, + this function searches for the corresponding lcssa phi node in exit + bb of LOOP. If it is found, return the phi result; otherwise return + NULL. */ + +static tree +find_guard_arg (class loop *loop, class loop *epilog ATTRIBUTE_UNUSED, + gphi *lcssa_phi) +{ + gphi_iterator gsi; + edge e = single_exit (loop); + + gcc_assert (single_pred_p (e->dest)); + for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gphi *phi = gsi.phi (); + if (operand_equal_p (PHI_ARG_DEF (phi, 0), + PHI_ARG_DEF (lcssa_phi, 0), 0)) + return PHI_RESULT (phi); + } + return NULL_TREE; +} + /* Function slpeel_tree_duplicate_loop_to_edge_cfg duplciates FIRST/SECOND from SECOND/FIRST and puts it at the original loop's preheader/exit edge, the two loops are arranged as below: @@ -2091,6 +2114,29 @@ slpeel_update_phi_nodes_for_loops (loop_vec_info loop_vinfo, incoming edge. */ adjust_phi_and_debug_stmts (update_phi, second_preheader_e, arg); } + + /* For epilogue peeling we have to make sure to copy all LC PHIs + for correct vectorization of live stmts. */ + if (loop == first) + { + basic_block orig_exit = single_exit (second)->dest; + for (gsi_orig = gsi_start_phis (orig_exit); + !gsi_end_p (gsi_orig); gsi_next (&gsi_orig)) + { + gphi *orig_phi = gsi_orig.phi (); + tree orig_arg = PHI_ARG_DEF (orig_phi, 0); + if (TREE_CODE (orig_arg) != SSA_NAME || virtual_operand_p (orig_arg)) + continue; + + /* Already created in the above loop. */ + if (find_guard_arg (first, second, orig_phi)) + continue; + + tree new_res = copy_ssa_name (orig_arg); + gphi *lcphi = create_phi_node (new_res, between_bb); + add_phi_arg (lcphi, orig_arg, single_exit (first), UNKNOWN_LOCATION); + } + } } /* Function slpeel_add_loop_guard adds guard skipping from the beginning @@ -2175,29 +2221,6 @@ slpeel_update_phi_nodes_for_guard1 (class loop *skip_loop, } } -/* LCSSA_PHI is a lcssa phi of EPILOG loop which is copied from LOOP, - this function searches for the corresponding lcssa phi node in exit - bb of LOOP. If it is found, return the phi result; otherwise return - NULL. */ - -static tree -find_guard_arg (class loop *loop, class loop *epilog ATTRIBUTE_UNUSED, - gphi *lcssa_phi) -{ - gphi_iterator gsi; - edge e = single_exit (loop); - - gcc_assert (single_pred_p (e->dest)); - for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gphi *phi = gsi.phi (); - if (operand_equal_p (PHI_ARG_DEF (phi, 0), - PHI_ARG_DEF (lcssa_phi, 0), 0)) - return PHI_RESULT (phi); - } - return NULL_TREE; -} - /* LOOP and EPILOG are two consecutive loops in CFG and EPILOG is copied from LOOP. Function slpeel_add_loop_guard adds guard skipping from a point between the two loops to the end of EPILOG. Edges GUARD_EDGE -- 2.30.2