diff mbox

Fix PR tree-optimization/50208

Message ID CAKSNEw7jJeW=RVu5FkDC3M8ofXZEJFdPKZN-JwZoQA7WXppxgA@mail.gmail.com
State New
Headers show

Commit Message

Ira Rosen Sept. 4, 2011, 9:23 a.m. UTC
Hi,

While analyzing def stmt in vectorizer pattern detection, we access
its stmt_vec_info which is initialized only for statements inside the
loop being analyzed. Hence if the def stmt is outside the loop, we get
a segfault. This patch checks that a statement is inside the loop
before accessing its stmt_vec_info.

Bootstrapped and tested on powerpc64-suse-linux.
Committed.

Ira

ChangeLog:

2011-09-04  Jakub Jelinek  <jakub@redhat.com>
            Ira Rosen  <ira.rosen@linaro.org>

     PR tree-optimization/50208
     * tree-vect-patterns.c (vect_handle_widen_mult_by_const):
     Add an argument.  Check that def_stmt is inside the loop.
    (vect_recog_widen_mult_pattern): Update calls to
    vect_handle_widen_mult_by_cons.
    (vect_operation_fits_smaller_type): Check that def_stmt is
    inside the loop.

testsuite/ChangeLog:

2011-09-04  Jakub Jelinek  <jakub@redhat.com>
            Ira Rosen  <ira.rosen@linaro.org>

     PR tree-optimization/50208
     * gcc.dg/vect/no-fre-pre-pr50208.c: New test.
     * gcc.dg/vect/vect.exp: Run no-fre-pre-*.c tests with
     -fno-tree-fre -fno-tree-pre.
diff mbox

Patch

Index: testsuite/gcc.dg/vect/no-fre-pre-pr50208.c
===================================================================
--- testsuite/gcc.dg/vect/no-fre-pre-pr50208.c  (revision 0)
+++ testsuite/gcc.dg/vect/no-fre-pre-pr50208.c  (revision 0)
@@ -0,0 +1,17 @@ 
+/* { dg-do compile } */
+
+char c;
+int a, b;
+
+void foo (int j)
+{
+  int i;
+  while (--j)
+    {
+      b = 3;
+      for (i = 0; i < 2; ++i)
+        a = b ^ c;
+    }
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
Index: testsuite/gcc.dg/vect/vect.exp
===================================================================
--- testsuite/gcc.dg/vect/vect.exp      (revision 178506)
+++ testsuite/gcc.dg/vect/vect.exp      (working copy)
@@ -263,6 +263,12 @@  lappend DEFAULT_VECTCFLAGS "-fno-tree-fre"
 dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-tree-fre-*.\[cS\]]]  \
         "" $DEFAULT_VECTCFLAGS

+# -fno-tree-fre -fno-tree-pre
+set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS
+lappend DEFAULT_VECTCFLAGS "-fno-tree-fre" "-fno-tree-pre"
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-fre-pre*.\[cS\]]]  \
+        "" $DEFAULT_VECTCFLAGS
+
 # Clean up.
 set dg-do-what-default ${save-dg-do-what-default}
Index: tree-vect-patterns.c
===================================================================
--- tree-vect-patterns.c        (revision 178506)
+++ tree-vect-patterns.c        (working copy)
@@ -344,12 +344,14 @@  vect_recog_dot_prod_pattern (VEC (gimple, heap) **
    replace a_T = (TYPE) a_t; with a_it - (interm_type) a_t;  */

 static bool
-vect_handle_widen_mult_by_const (tree const_oprnd, tree *oprnd,
+vect_handle_widen_mult_by_const (gimple stmt, tree const_oprnd, tree *oprnd,
                                 VEC (gimple, heap) **stmts, tree type,
                                 tree *half_type, gimple def_stmt)
 {
   tree new_type, new_oprnd, tmp;
   gimple new_stmt;
+  loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (vinfo_for_stmt (stmt));
+  struct loop *loop = LOOP_VINFO_LOOP (loop_info);

   if (int_fits_type_p (const_oprnd, *half_type))
     {
@@ -359,6 +361,8 @@  static bool
     }

   if (TYPE_PRECISION (type) < (TYPE_PRECISION (*half_type) * 4)
+      || !gimple_bb (def_stmt)
+      || !flow_bb_inside_loop_p (loop, gimple_bb (def_stmt))
       || !vinfo_for_stmt (def_stmt))
     return false;

@@ -527,7 +531,8 @@  vect_recog_widen_mult_pattern (VEC (gimple, heap)
     {
       if (TREE_CODE (oprnd0) == INTEGER_CST
          && TREE_CODE (half_type1) == INTEGER_TYPE
-          && vect_handle_widen_mult_by_const (oprnd0, &oprnd1, stmts, type,
+          && vect_handle_widen_mult_by_const (last_stmt, oprnd0, &oprnd1,
+                                              stmts, type,
                                              &half_type1, def_stmt1))
         half_type0 = half_type1;
       else
@@ -537,7 +542,8 @@  vect_recog_widen_mult_pattern (VEC (gimple, heap)
     {
       if (TREE_CODE (oprnd1) == INTEGER_CST
           && TREE_CODE (half_type0) == INTEGER_TYPE
-          && vect_handle_widen_mult_by_const (oprnd1, &oprnd0, stmts, type,
+          && vect_handle_widen_mult_by_const (last_stmt, oprnd1, &oprnd0,
+                                              stmts, type,
                                              &half_type0, def_stmt0))
         half_type1 = half_type0;
       else
@@ -868,6 +874,8 @@  vect_operation_fits_smaller_type (gimple stmt, tre
   tree interm_type = NULL_TREE, half_type, tmp, new_oprnd, type;
   gimple def_stmt, new_stmt;
   bool first = false;
+  loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (vinfo_for_stmt (stmt));
+  struct loop *loop = LOOP_VINFO_LOOP (loop_info);

   *new_def_stmt = NULL;

@@ -898,6 +906,8 @@  vect_operation_fits_smaller_type (gimple stmt, tre
     {
       first = true;
       if (!widened_name_p (oprnd, stmt, &half_type, &def_stmt, false)
+          || !gimple_bb (def_stmt)
+          || !flow_bb_inside_loop_p (loop, gimple_bb (def_stmt))
           || !vinfo_for_stmt (def_stmt))
         return false;
     }