https://gcc.gnu.org/g:1d11536881e60f36a2b8ad9919169ac7a8bc0e3e

commit r14-10813-g1d11536881e60f36a2b8ad9919169ac7a8bc0e3e
Author: Richard Biener <rguent...@suse.de>
Date:   Mon Oct 7 11:05:17 2024 +0200

    tree-optimization/116982 - analyze scalar loop exit early
    
    The following makes sure to discover the scalar loop IV exit during
    analysis as failure to do so (if DCE and friends are disabled this
    can happen due to if-conversion doing DCE and FRE on the if-converted
    loop) would ICE later.
    
    I refrained from larger refactoring to be able to eventually backport.
    
            PR tree-optimization/116982
            * tree-vectorizer.h (vect_analyze_loop): Pass in .LOOP_VECTORIZED
            call.
            (vect_analyze_loop_form): Likewise.
            * tree-vect-loop.cc (vect_analyze_loop_form): Reject loops where we
            cannot determine a IV exit for the scalar loop.
            (vect_analyze_loop): Adjust.
            * tree-vectorizer.cc (try_vectorize_loop_1): Likewise.
            * tree-parloops.cc (gather_scalar_reductions): Likewise.
    
    (cherry picked from commit 9b86efd5210101954bd187c3aa8bb909610a5746)

Diff:
---
 gcc/tree-parloops.cc   |  4 ++--
 gcc/tree-vect-loop.cc  | 23 +++++++++++++++++++----
 gcc/tree-vectorizer.cc |  3 ++-
 gcc/tree-vectorizer.h  |  6 ++++--
 4 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/gcc/tree-parloops.cc b/gcc/tree-parloops.cc
index 888a834faf91..4d7a4ec94378 100644
--- a/gcc/tree-parloops.cc
+++ b/gcc/tree-parloops.cc
@@ -3304,7 +3304,7 @@ gather_scalar_reductions (loop_p loop, 
reduction_info_table_type *reduction_list
 
   vec_info_shared shared;
   vect_loop_form_info info;
-  if (!vect_analyze_loop_form (loop, &info))
+  if (!vect_analyze_loop_form (loop, NULL, &info))
     goto gather_done;
 
   simple_loop_info = vect_create_loop_vinfo (loop, &shared, &info);
@@ -3346,7 +3346,7 @@ gather_scalar_reductions (loop_p loop, 
reduction_info_table_type *reduction_list
     {
       vec_info_shared shared;
       vect_loop_form_info info;
-      if (vect_analyze_loop_form (loop->inner, &info))
+      if (vect_analyze_loop_form (loop->inner, NULL, &info))
        {
          simple_loop_info
            = vect_create_loop_vinfo (loop->inner, &shared, &info);
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 744044735d39..dfb9d1be6670 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -1734,7 +1734,8 @@ vect_compute_single_scalar_iteration_cost (loop_vec_info 
loop_vinfo)
      niter could be analyzed under some assumptions.  */
 
 opt_result
-vect_analyze_loop_form (class loop *loop, vect_loop_form_info *info)
+vect_analyze_loop_form (class loop *loop, gimple *loop_vectorized_call,
+                       vect_loop_form_info *info)
 {
   DUMP_VECT_SCOPE ("vect_analyze_loop_form");
 
@@ -1744,6 +1745,18 @@ vect_analyze_loop_form (class loop *loop, 
vect_loop_form_info *info)
                                   "not vectorized:"
                                   " could not determine main exit from"
                                   " loop with multiple exits.\n");
+  if (loop_vectorized_call)
+    {
+      tree arg = gimple_call_arg (loop_vectorized_call, 1);
+      class loop *scalar_loop = get_loop (cfun, tree_to_shwi (arg));
+      edge scalar_exit_e = vec_init_loop_exit_info (scalar_loop);
+      if (!scalar_exit_e)
+       return opt_result::failure_at (vect_location,
+                                      "not vectorized:"
+                                      " could not determine main exit from"
+                                      " loop with multiple exits.\n");
+    }
+
   info->loop_exit = exit_e;
   if (dump_enabled_p ())
       dump_printf_loc (MSG_NOTE, vect_location,
@@ -1815,7 +1828,7 @@ vect_analyze_loop_form (class loop *loop, 
vect_loop_form_info *info)
 
       /* Analyze the inner-loop.  */
       vect_loop_form_info inner;
-      opt_result res = vect_analyze_loop_form (loop->inner, &inner);
+      opt_result res = vect_analyze_loop_form (loop->inner, NULL, &inner);
       if (!res)
        {
          if (dump_enabled_p ())
@@ -3570,7 +3583,8 @@ vect_analyze_loop_1 (class loop *loop, vec_info_shared 
*shared,
    for it.  The different analyses will record information in the
    loop_vec_info struct.  */
 opt_loop_vec_info
-vect_analyze_loop (class loop *loop, vec_info_shared *shared)
+vect_analyze_loop (class loop *loop, gimple *loop_vectorized_call,
+                  vec_info_shared *shared)
 {
   DUMP_VECT_SCOPE ("analyze_loop_nest");
 
@@ -3588,7 +3602,8 @@ vect_analyze_loop (class loop *loop, vec_info_shared 
*shared)
 
   /* Analyze the loop form.  */
   vect_loop_form_info loop_form_info;
-  opt_result res = vect_analyze_loop_form (loop, &loop_form_info);
+  opt_result res = vect_analyze_loop_form (loop, loop_vectorized_call,
+                                          &loop_form_info);
   if (!res)
     {
       if (dump_enabled_p ())
diff --git a/gcc/tree-vectorizer.cc b/gcc/tree-vectorizer.cc
index 9001b738bf31..6062355b781d 100644
--- a/gcc/tree-vectorizer.cc
+++ b/gcc/tree-vectorizer.cc
@@ -1063,7 +1063,8 @@ try_vectorize_loop_1 (hash_table<simduid_to_vf> 
*&simduid_to_vf_htab,
                 LOCATION_LINE (vect_location.get_location_t ()));
 
   /* Try to analyze the loop, retaining an opt_problem if dump_enabled_p.  */
-  opt_loop_vec_info loop_vinfo = vect_analyze_loop (loop, &shared);
+  opt_loop_vec_info loop_vinfo = vect_analyze_loop (loop, loop_vectorized_call,
+                                                   &shared);
   loop->aux = loop_vinfo;
 
   if (!loop_vinfo)
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index c076cb648f4b..de7ed5758a69 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -2392,7 +2392,8 @@ extern bool check_reduction_path (dump_user_location_t, 
loop_p, gphi *, tree,
                                  enum tree_code);
 extern bool needs_fold_left_reduction_p (tree, code_helper);
 /* Drive for loop analysis stage.  */
-extern opt_loop_vec_info vect_analyze_loop (class loop *, vec_info_shared *);
+extern opt_loop_vec_info vect_analyze_loop (class loop *, gimple *,
+                                           vec_info_shared *);
 extern tree vect_build_loop_niters (loop_vec_info, bool * = NULL);
 extern void vect_gen_vector_loop_niters (loop_vec_info, tree, tree *,
                                         tree *, bool);
@@ -2423,7 +2424,8 @@ struct vect_loop_form_info
   gcond *inner_loop_cond;
   edge loop_exit;
 };
-extern opt_result vect_analyze_loop_form (class loop *, vect_loop_form_info *);
+extern opt_result vect_analyze_loop_form (class loop *, gimple *,
+                                         vect_loop_form_info *);
 extern loop_vec_info vect_create_loop_vinfo (class loop *, vec_info_shared *,
                                             const vect_loop_form_info *,
                                             loop_vec_info = nullptr);

Reply via email to