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





Reply via email to