Hi!

A recent change in vect_init_vector emits new statements into a gimple_seq
stmts and then calls vect_init_vector_1 on each of those statements.

This doesn't work well, because vect_init_vector_1 places the given
statement into another sequence (body of some bb, on the edge, ...),
and when the caller holds a gimple_stmt_iterator pointing to that statement
across its insertion into another sequence the ->prev/->next bookkeeping may
go wrong, such as on the testcase where stmt == stmt->prev == stmt->next
because of that.

Fixed by first removing the statement from the stmts sequence (thus
gsi_remove already updates the iterator to the next statement).

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2019-07-04  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/91063
        * tree-vect-stmts.c (vect_init_vector): Call gsi_remove to remove
        stmt from stmts sequence before calling vect_init_vector_1.
        Formatting fix.

        * gcc.dg/gomp/pr91063.c: New test.

--- gcc/tree-vect-stmts.c.jj    2019-07-03 10:24:33.463768431 +0200
+++ gcc/tree-vect-stmts.c       2019-07-03 12:35:48.998435660 +0200
@@ -1496,15 +1496,19 @@ vect_init_vector (stmt_vec_info stmt_inf
                   promotion of invariant/external defs.  */
                val = gimple_convert (&stmts, TREE_TYPE (type), val);
              for (gimple_stmt_iterator gsi2 = gsi_start (stmts);
-                  !gsi_end_p (gsi2); gsi_next (&gsi2))
-               vect_init_vector_1 (stmt_info, gsi_stmt (gsi2), gsi);
+                  !gsi_end_p (gsi2); )
+               {
+                 init_stmt = gsi_stmt (gsi2);
+                 gsi_remove (&gsi2, false);
+                 vect_init_vector_1 (stmt_info, init_stmt, gsi);
+               }
            }
        }
       val = build_vector_from_val (type, val);
     }
 
   new_temp = vect_get_new_ssa_name (type, vect_simple_var, "cst_");
-  init_stmt = gimple_build_assign  (new_temp, val);
+  init_stmt = gimple_build_assign (new_temp, val);
   vect_init_vector_1 (stmt_info, init_stmt, gsi);
   return new_temp;
 }
--- gcc/testsuite/gcc.dg/gomp/pr91063.c.jj      2019-07-03 12:50:55.123799217 
+0200
+++ gcc/testsuite/gcc.dg/gomp/pr91063.c 2019-07-03 12:50:43.320989864 +0200
@@ -0,0 +1,17 @@
+/* PR tree-optimization/91063 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fopenmp-simd" } */
+/* { dg-additional-options "-mavx512f" { target { i?86-*-* x86_64-*-* } } } */
+
+struct S { void *s; };
+
+int
+foo (struct S *x)
+{
+  int r = 0;
+  int i;
+#pragma omp simd reduction (+ : r)
+  for (i = 0; i < 64; ++i)
+    r += (int) (x->s != 0);
+  return r;
+}

        Jakub

Reply via email to