On Mon, Jun 13, 2016 at 1:00 PM, Alan Hayward <alan.hayw...@arm.com> wrote: > vectorizable_live_operation checks that there is exactly one use of each > operation that has been marked live. > > However, it is possible for the operation is used more than once if the > usage PHIs are identical. > > For example in 71416-1.c, _6 is used twice after the loop in bb 9. > > <bb 8>: > # e.6_21 = PHI <e.6_20(7), _9(10)> > _5 = g_16(D) >= 0; > _6 = (int) _5; > e.5_7 = (unsigned char) e.6_21; > _8 = e.5_7 + 1; > _9 = (char) _8; > if (_9 != 0) > goto <bb 10>; > else > goto <bb 9>; > > <bb 9>: > # _12 = PHI <_6(8)> > # _19 = PHI <_6(8)> > goto <bb 12>;
Wonder where this inefficiency comes from ... > > This patch relaxes the restriction in vectorizable_live_operation, and now > makes sure there is at least one use of each operation that has been marked > live. > > Tested on x86 and aarch64. > Ok to commit? Ok. Thanks, Richard. > gcc/ > PR tree-optimization/71416 > * tree-vect-loop.c (vectorizable_live_operation): Let worklist have > multiple entries > > > Alan. > > > diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c > index > 90ade75bcd212b542ad680877a79df717751ff4b..4c8678505df6ec572b69fd7d12ac55cf4 > 619ece6 100644 > --- a/gcc/tree-vect-loop.c > +++ b/gcc/tree-vect-loop.c > @@ -6355,7 +6355,7 @@ vectorizable_live_operation (gimple *stmt, > FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, lhs) > if (!flow_bb_inside_loop_p (loop, gimple_bb (use_stmt))) > worklist.safe_push (use_stmt); > - gcc_assert (worklist.length () == 1); > + gcc_assert (worklist.length () >= 1); > > bitsize = TYPE_SIZE (TREE_TYPE (vectype)); > vec_bitsize = TYPE_SIZE (vectype); > @@ -6413,9 +6413,12 @@ vectorizable_live_operation (gimple *stmt, > > /* Replace all uses of the USE_STMT in the worklist with the newly > inserted > statement. */ > - use_stmt = worklist.pop (); > - replace_uses_by (gimple_phi_result (use_stmt), new_tree); > - update_stmt (use_stmt); > + while (!worklist.is_empty ()) > + { > + use_stmt = worklist.pop (); > + replace_uses_by (gimple_phi_result (use_stmt), new_tree); > + update_stmt (use_stmt); > + } > > return true; > } > > > > >