]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/116982 - analyze scalar loop exit early
authorRichard Biener <rguenther@suse.de>
Mon, 7 Oct 2024 09:05:17 +0000 (11:05 +0200)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 7 Oct 2024 11:57:39 +0000 (13:57 +0200)
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.

gcc/tree-parloops.cc
gcc/tree-vect-loop.cc
gcc/tree-vectorizer.cc
gcc/tree-vectorizer.h

index f4468658732b4aaa85c3afda409a15e1f6198636..6a1249bebb63ae34cc5e81383781f6d3fbfcc73c 100644 (file)
@@ -3305,7 +3305,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);
@@ -3347,7 +3347,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);
index f1b3fb2e44ac64f71310eb5208822e147af95cfa..bbadf21efe0f72c7002d8bcd01e6a921006f8209 100644 (file)
@@ -1737,7 +1737,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");
 
@@ -1747,6 +1748,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,
@@ -1819,7 +1832,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 ())
@@ -3520,7 +3533,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");
 
@@ -3538,7 +3552,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 ())
index d4ab47349a3a80181710698274acfcf80963231f..fed12c41f9cb1aa0a3322bda53338f46c548588a 100644 (file)
@@ -1067,7 +1067,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)
index 490061aea2f6d465d9589eb97bbd34a920d76b1c..73bccb5a40a8be4d3f5f600239d63c756d2e35e7 100644 (file)
@@ -2460,7 +2460,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);
@@ -2495,7 +2496,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);