This fixes PR53408, we ICE when we encounter an unhandled situation
in induction handling for outer loop vectorization - the fix is to
properly reject this at analysis time rather than asserting and
ICEing, of course.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2012-05-21  Richard Guenther  <rguent...@suse.de>

        PR tree-optimization/53408
        * tree-vect-loop.c (vectorizable_induction): Properly check
        the restriction that we cannot handle induction results from
        the inner loop outside of the outer loop.

        * gcc.dg/torture/pr53408.c: New testcase.

Index: gcc/tree-vect-loop.c
===================================================================
*** gcc/tree-vect-loop.c        (revision 187706)
--- gcc/tree-vect-loop.c        (working copy)
*************** vectorizable_induction (gimple phi, gimp
*** 5061,5072 ****
    tree vec_def;
  
    gcc_assert (ncopies >= 1);
!   /* FORNOW. This restriction should be relaxed.  */
!   if (nested_in_vect_loop_p (loop, phi) && ncopies > 1)
      {
!       if (vect_print_dump_info (REPORT_DETAILS))
!         fprintf (vect_dump, "multiple types in nested loop.");
!       return false;
      }
  
    if (!STMT_VINFO_RELEVANT_P (stmt_info))
--- 5061,5106 ----
    tree vec_def;
  
    gcc_assert (ncopies >= 1);
!   /* FORNOW. These restrictions should be relaxed.  */
!   if (nested_in_vect_loop_p (loop, phi))
      {
!       imm_use_iterator imm_iter;
!       use_operand_p use_p;
!       gimple exit_phi;
!       edge latch_e;
!       tree loop_arg;
! 
!       if (ncopies > 1)
!       {
!         if (vect_print_dump_info (REPORT_DETAILS))
!           fprintf (vect_dump, "multiple types in nested loop.");
!         return false;
!       }
! 
!       exit_phi = NULL;
!       latch_e = loop_latch_edge (loop->inner);
!       loop_arg = PHI_ARG_DEF_FROM_EDGE (phi, latch_e);
!       FOR_EACH_IMM_USE_FAST (use_p, imm_iter, loop_arg)
!       {
!         if (!flow_bb_inside_loop_p (loop->inner,
!                                     gimple_bb (USE_STMT (use_p))))
!           {
!             exit_phi = USE_STMT (use_p);
!             break;
!           }
!       }
!       if (exit_phi)
!       {
!         stmt_vec_info exit_phi_vinfo  = vinfo_for_stmt (exit_phi);
!         if (!(STMT_VINFO_RELEVANT_P (exit_phi_vinfo)
!               && !STMT_VINFO_LIVE_P (exit_phi_vinfo)))
!           {
!             if (vect_print_dump_info (REPORT_DETAILS))
!               fprintf (vect_dump, "inner-loop induction only used outside "
!                        "of the outer vectorized loop.");
!             return false;
!           }
!       }
      }
  
    if (!STMT_VINFO_RELEVANT_P (stmt_info))
Index: gcc/testsuite/gcc.dg/torture/pr53408.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr53408.c      (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr53408.c      (revision 0)
***************
*** 0 ****
--- 1,20 ----
+ /* { dg-do compile } */
+ 
+ int a, b, c, d, e;
+ void
+ fn1 ()
+ {
+   int f, g;
+   char h = 0;
+   b = 0;
+   for (; b < 32; b++)
+     {
+       g = h > e ? h : h << 1;
+       f = g && a ? 0 : 1;
+       h = 1;
+       for (; h > 0; h = h + 1)
+       c = 0 < h | f;
+     }
+   if (h)
+     d = 0;
+ }

Reply via email to