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>; 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? 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; }