On Mon, 22 Aug 2016, Dominique d'Humières wrote:

> This patch causes:
> 
> FAIL: gfortran.dg/vect/pr69466.f90   -O  (internal compiler error)
> FAIL: gfortran.dg/vect/pr69466.f90   -O  (test for excess errors)
> with -m32.
> 
> [Book15] f90/bug% gfc 
> /opt/gcc/_clean/gcc/testsuite/gfortran.dg/vect/pr69466.f90 -O2 
> -ftree-vectorize -m32 -march=core-avx2
> /opt/gcc/_clean/gcc/testsuite/gfortran.dg/vect/pr69466.f90:4:0:
> 
>   subroutine foo
>  
> internal compiler error: in slpeel_duplicate_current_defs_from_edges, at 
> tree-vect-loop-manip.c:750

Somehow missed that.  I am testing the following.

Richard.

2016-08-23  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/77286
        * tree-vect-loop.c (vect_analyze_loop_form_1): Do not modify
        the CFG here.
        (vect_transform_loop): Split exit edges of loop and scalar
        loop if required and at the appropriate time.

Index: gcc/tree-vect-loop.c
===================================================================
--- gcc/tree-vect-loop.c        (revision 239684)
+++ gcc/tree-vect-loop.c        (working copy)
@@ -1486,23 +1498,14 @@ vect_analyze_loop_form_1 (struct loop *l
       return false;
     }
 
-  /* Make sure there exists a single-predecessor exit bb:  */
-  if (!single_pred_p (single_exit (loop)->dest))
+  /* Make sure the exit is not abnormal.  */
+  edge e = single_exit (loop);
+  if (e->flags & EDGE_ABNORMAL)
     {
-      edge e = single_exit (loop);
-      if (!(e->flags & EDGE_ABNORMAL))
-       {
-         split_loop_exit_edge (e);
-         if (dump_enabled_p ())
-           dump_printf (MSG_NOTE, "split exit edge.\n");
-       }
-      else
-       {
-         if (dump_enabled_p ())
-           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-                            "not vectorized: abnormal loop exit edge.\n");
-         return false;
-       }
+      if (dump_enabled_p ())
+       dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                        "not vectorized: abnormal loop exit edge.\n");
+      return false;
     }
 
   *loop_cond = vect_get_loop_niters (loop, assumptions, number_of_iterations,
@@ -6759,6 +6766,16 @@ vect_transform_loop (loop_vec_info loop_
       check_profitability = true;
     }
 
+  /* Make sure there exists a single-predecessor exit bb.  Do this before 
+     versioning.   */
+  edge e = single_exit (loop);
+  if (! single_pred_p (e->dest))
+    {
+      split_loop_exit_edge (e);
+      if (dump_enabled_p ())
+       dump_printf (MSG_NOTE, "split exit edge\n");
+    }
+
   /* Version the loop first, if required, so the profitability check
      comes first.  */
 
@@ -6768,6 +6785,22 @@ vect_transform_loop (loop_vec_info loop_
       check_profitability = false;
     }
 
+  /* Make sure there exists a single-predecessor exit bb also on the
+     scalar loop copy.  Do this after versioning but before peeling
+     so CFG structure is fine for both scalar and if-converted loop
+     to make slpeel_duplicate_current_defs_from_edges face matched
+     loop closed PHI nodes on the exit.  */
+  if (LOOP_VINFO_SCALAR_LOOP (loop_vinfo))
+    {
+      e = single_exit (LOOP_VINFO_SCALAR_LOOP (loop_vinfo));
+      if (! single_pred_p (e->dest))
+       {
+         split_loop_exit_edge (e);
+         if (dump_enabled_p ())
+           dump_printf (MSG_NOTE, "split exit edge of scalar loop\n");
+       }
+    }
+
   tree ni_name = vect_build_loop_niters (loop_vinfo);
   LOOP_VINFO_NITERS_UNCHANGED (loop_vinfo) = ni_name;
 

Reply via email to