Hi All,

This has loop versioning use the vectorizer's IV exit edge when it's available
since single_exit (..) fails with multiple exits.

Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.

Ok for master?

Thanks,
Tamar

gcc/ChangeLog:

        * tree-vect-loop-manip.cc (vect_loop_versioning): Support multiple
        exits.

--- inline copy of patch -- 
diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
index 
3d59119787d6afdc5a6465a547d1ea2d3d940373..58b4b9c11d8b844ee86156cdfcba7f838030a7c2
 100644
--- a/gcc/tree-vect-loop-manip.cc
+++ b/gcc/tree-vect-loop-manip.cc
@@ -4180,12 +4180,24 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
         If loop versioning wasn't done from loop, but scalar_loop instead,
         merge_bb will have already just a single successor.  */
 
-      merge_bb = single_exit (loop_to_version)->dest;
+      /* Due to the single_exit check above we should only get here when
+        loop == loop_to_version, that means we can use loop_vinfo to get the
+        exits.  */
+      edge exit_edge = single_exit (loop_to_version);
+      if (LOOP_VINFO_EARLY_BREAKS (loop_vinfo))
+       {
+         /* In early exits the main exit will fail into the merge block of the
+            alternative exits.  So we need the single successor of the main
+            exit here to find the merge block.  */
+         exit_edge = LOOP_VINFO_IV_EXIT (loop_vinfo);
+       }
+      gcc_assert (exit_edge);
+      merge_bb = exit_edge->dest;
       if (EDGE_COUNT (merge_bb->preds) >= 2)
        {
          gcc_assert (EDGE_COUNT (merge_bb->preds) >= 2);
-         new_exit_bb = split_edge (single_exit (loop_to_version));
-         new_exit_e = single_exit (loop_to_version);
+         new_exit_bb = split_edge (exit_edge);
+         new_exit_e = exit_edge;
          e = EDGE_SUCC (new_exit_bb, 0);
 
          for (gsi = gsi_start_phis (merge_bb); !gsi_end_p (gsi);




-- 
diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
index 
3d59119787d6afdc5a6465a547d1ea2d3d940373..58b4b9c11d8b844ee86156cdfcba7f838030a7c2
 100644
--- a/gcc/tree-vect-loop-manip.cc
+++ b/gcc/tree-vect-loop-manip.cc
@@ -4180,12 +4180,24 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
         If loop versioning wasn't done from loop, but scalar_loop instead,
         merge_bb will have already just a single successor.  */
 
-      merge_bb = single_exit (loop_to_version)->dest;
+      /* Due to the single_exit check above we should only get here when
+        loop == loop_to_version, that means we can use loop_vinfo to get the
+        exits.  */
+      edge exit_edge = single_exit (loop_to_version);
+      if (LOOP_VINFO_EARLY_BREAKS (loop_vinfo))
+       {
+         /* In early exits the main exit will fail into the merge block of the
+            alternative exits.  So we need the single successor of the main
+            exit here to find the merge block.  */
+         exit_edge = LOOP_VINFO_IV_EXIT (loop_vinfo);
+       }
+      gcc_assert (exit_edge);
+      merge_bb = exit_edge->dest;
       if (EDGE_COUNT (merge_bb->preds) >= 2)
        {
          gcc_assert (EDGE_COUNT (merge_bb->preds) >= 2);
-         new_exit_bb = split_edge (single_exit (loop_to_version));
-         new_exit_e = single_exit (loop_to_version);
+         new_exit_bb = split_edge (exit_edge);
+         new_exit_e = exit_edge;
          e = EDGE_SUCC (new_exit_bb, 0);
 
          for (gsi = gsi_start_phis (merge_bb); !gsi_end_p (gsi);



Reply via email to