diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a0f35e63327b..11f9e0e56a13 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2018-11-05 Richard Biener + + PR tree-optimization/87873 + * tree-ssa-loop-manip.h (split_loop_exit_edge): Add copy_constants_p + argument. + * tree-ssa-loop-manip.c (split_loop_exit_edge): Likewise. + * tree-vect-loop.c (vect_transform_loop): When splitting the + loop exit also create forwarder PHIs for constants. + * tree-vect-loop-manip.c (slpeel_duplicate_current_defs_from_edges): + Handle constant to_arg, add extra checking we match up the correct + PHIs. + 2018-11-05 Robin Dapp * config/s390/s390.md: QImode and HImode for load on condition. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ae7ed523955e..9001057f89c7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,4 +1,9 @@ -2018-10-26 Robin Dapp +2018-11-05 Richard Biener + + PR tree-optimization/87873 + * gcc.dg/pr87873.c: New testcase. + +2018-11-05 Robin Dapp * gcc.target/s390/ifcvt-one-insn-bool.c: New test. * gcc.target/s390/ifcvt-one-insn-char.c: New test. diff --git a/gcc/testsuite/gcc.dg/pr87873.c b/gcc/testsuite/gcc.dg/pr87873.c new file mode 100644 index 000000000000..63d05342b40f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr87873.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O -ftree-loop-vectorize" } */ + +long k3; +int gs; + +void +s2 (int aj) +{ + while (aj < 1) + { + gs ^= 1; + k3 = (long) gs * 2; + if (k3 != 0) + k3 = 0; + + ++aj; + } +} diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c index 5acee6c98f32..726590ac6df1 100644 --- a/gcc/tree-ssa-loop-manip.c +++ b/gcc/tree-ssa-loop-manip.c @@ -773,10 +773,12 @@ verify_loop_closed_ssa (bool verify_ssa_p, struct loop *loop) } /* Split loop exit edge EXIT. The things are a bit complicated by a need to - preserve the loop closed ssa form. The newly created block is returned. */ + preserve the loop closed ssa form. If COPY_CONSTANTS_P is true then + forwarder PHIs are also created for constant arguments. + The newly created block is returned. */ basic_block -split_loop_exit_edge (edge exit) +split_loop_exit_edge (edge exit, bool copy_constants_p) { basic_block dest = exit->dest; basic_block bb = split_edge (exit); @@ -796,12 +798,13 @@ split_loop_exit_edge (edge exit) /* If the argument of the PHI node is a constant, we do not need to keep it inside loop. */ - if (TREE_CODE (name) != SSA_NAME) + if (TREE_CODE (name) != SSA_NAME + && !copy_constants_p) continue; /* Otherwise create an auxiliary phi node that will copy the value of the SSA name out of the loop. */ - new_name = duplicate_ssa_name (name, NULL); + new_name = duplicate_ssa_name (PHI_RESULT (phi), NULL); new_phi = create_phi_node (new_name, bb); add_phi_arg (new_phi, name, exit, locus); SET_USE (op_p, new_name); diff --git a/gcc/tree-ssa-loop-manip.h b/gcc/tree-ssa-loop-manip.h index 390ac6f82783..ddda5cf75158 100644 --- a/gcc/tree-ssa-loop-manip.h +++ b/gcc/tree-ssa-loop-manip.h @@ -37,7 +37,7 @@ checking_verify_loop_closed_ssa (bool verify_ssa_p, struct loop *loop = NULL) verify_loop_closed_ssa (verify_ssa_p, loop); } -extern basic_block split_loop_exit_edge (edge); +extern basic_block split_loop_exit_edge (edge, bool = false); extern basic_block ip_end_pos (struct loop *); extern basic_block ip_normal_pos (struct loop *); extern void standard_iv_increment_position (struct loop *, diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c index 1d1d1147696f..f1b023b4e4e0 100644 --- a/gcc/tree-vect-loop-manip.c +++ b/gcc/tree-vect-loop-manip.c @@ -977,10 +977,15 @@ slpeel_duplicate_current_defs_from_edges (edge from, edge to) } if (TREE_CODE (from_arg) != SSA_NAME) gcc_assert (operand_equal_p (from_arg, to_arg, 0)); - else + else if (TREE_CODE (to_arg) == SSA_NAME) { if (get_current_def (to_arg) == NULL_TREE) - set_current_def (to_arg, get_current_def (from_arg)); + { + gcc_assert (types_compatible_p (TREE_TYPE (to_arg), + TREE_TYPE (get_current_def + (from_arg)))); + set_current_def (to_arg, get_current_def (from_arg)); + } } gsi_next (&gsi_from); gsi_next (&gsi_to); diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 177b284e9c61..41a46c2d234e 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -8196,7 +8196,7 @@ vect_transform_loop (loop_vec_info loop_vinfo) edge e = single_exit (loop); if (! single_pred_p (e->dest)) { - split_loop_exit_edge (e); + split_loop_exit_edge (e, true); if (dump_enabled_p ()) dump_printf (MSG_NOTE, "split exit edge\n"); }