re PR tree-optimization/66856 (ICE in compute_live_loop_exits, at tree-ssa-loop-manip...
authorRichard Biener <rguenther@suse.de>
Fri, 15 Jan 2016 15:43:48 +0000 (15:43 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 15 Jan 2016 15:43:48 +0000 (15:43 +0000)
2016-01-15  Richard Biener  <rguenther@suse.de>

PR tree-optimization/66856
* tree-vect-loop.c (vect_transform_loop): Free SLP instances here.
* tree-vect-slp.c (vect_free_slp_tree): Decrement stmt reference count.
(vect_create_new_slp_node): Increment stmt reference count.
(vect_get_and_check_slp_defs): Make sure stmts are nor already in
an SLP tree before swapping operands.
(vect_build_slp_tree): Likewise.
(destroy_bb_vec_info): Free stmt info after SLP instances.
* tree-vect-stmts.c (new_stmt_vec_info): Initialize reference count.
* tree-vectorizer.h (struct _stmt_vec_info): Add num_slp_uses field.
(STMT_VINFO_NUM_SLP_USES): New macro.

* gcc.dg/torture/pr66856-1.c: New testcase.
* gcc.dg/torture/pr66856-2.c: Likewise.

From-SVN: r232435

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr66856-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr66856-2.c [new file with mode: 0644]
gcc/tree-vect-loop.c
gcc/tree-vect-slp.c
gcc/tree-vect-stmts.c
gcc/tree-vectorizer.h

index 675893e69931d207ae629e23116c645e1aa18c6f..067fb0757952fca73e4d0e6fd4c8933a4d7e7a7f 100644 (file)
@@ -1,3 +1,17 @@
+2016-01-15  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/66856
+       * tree-vect-loop.c (vect_transform_loop): Free SLP instances here.
+       * tree-vect-slp.c (vect_free_slp_tree): Decrement stmt reference count.
+       (vect_create_new_slp_node): Increment stmt reference count.
+       (vect_get_and_check_slp_defs): Make sure stmts are nor already in
+       an SLP tree before swapping operands.
+       (vect_build_slp_tree): Likewise.
+       (destroy_bb_vec_info): Free stmt info after SLP instances.
+       * tree-vect-stmts.c (new_stmt_vec_info): Initialize reference count.
+       * tree-vectorizer.h (struct _stmt_vec_info): Add num_slp_uses field.
+       (STMT_VINFO_NUM_SLP_USES): New macro.
+
 2016-01-15  Richard Biener  <rguenther@suse.de>
 
        PR debug/69137
index a09358502f6775a8512dd7231cc623ebdac0f03b..bc6105d922eea54c5afe56e9dddde265a4d23dc0 100644 (file)
@@ -1,3 +1,9 @@
+2016-01-15  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/66856
+       * gcc.dg/torture/pr66856-1.c: New testcase.
+       * gcc.dg/torture/pr66856-2.c: Likewise.
+
 2016-01-15  Richard Biener  <rguenther@suse.de>
 
        PR debug/69137
diff --git a/gcc/testsuite/gcc.dg/torture/pr66856-1.c b/gcc/testsuite/gcc.dg/torture/pr66856-1.c
new file mode 100644 (file)
index 0000000..9da89fb
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mavx2" { target x86_64-*-* i?86-*-* } } */
+
+short c;
+int d;
+int fn1(int p1, int p2) {
+    int a, b;
+    a = p1 >> 3 & p2;
+    b = p1 & 072;
+    a |= a >> 5;
+    a |= b >> 5;
+    return a;
+}
+void fn2() {
+    short *e = &c;
+    int *f;
+    int g;
+    while (d -= 4) {
+       fn1(1, 1);
+       fn1(1, 1) * fn1(1, 1) * fn1(1, 1);
+       *e++ = fn1(*f++, g);
+       *e++ = fn1(*f++, g);
+    }
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr66856-2.c b/gcc/testsuite/gcc.dg/torture/pr66856-2.c
new file mode 100644 (file)
index 0000000..5089085
--- /dev/null
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+
+typedef int uint32_t;
+int c, e, f, g, h;
+short *d;
+uint32_t fn1(uint32_t p1, uint32_t p2)
+{
+  uint32_t a, b;
+  a = p1 >> 3 & p2;
+  b = p1 & 072;
+  a |= a >> 5;
+  a |= b >> 5;
+  return a;
+}
+
+void fn2()
+{
+  uint32_t *i;
+  uint32_t j;
+  while (c -= 4) {
+      fn1(e, j);
+      fn1(f, j) * fn1(g, j) * fn1(h, j);
+      *d++ = fn1(*i++, j);
+      *d++ = fn1(*i++, j);
+  }
+}
index 83ded8b7fb2f7bfb897b1249eb9aa23555d4a33c..60346725a441bf6bad7594b7f09abcbb23e5e06e 100644 (file)
@@ -6930,4 +6930,11 @@ vect_transform_loop (loop_vec_info loop_vinfo)
                         "OUTER LOOP VECTORIZED\n");
       dump_printf (MSG_NOTE, "\n");
     }
+
+  /* Free SLP instances here because otherwise stmt reference counting
+     won't work.  */
+  slp_instance instance;
+  FOR_EACH_VEC_ELT (LOOP_VINFO_SLP_INSTANCES (loop_vinfo), i, instance)
+    vect_free_slp_instance (instance);
+  LOOP_VINFO_SLP_INSTANCES (loop_vinfo).release ();
 }
index fe422f858fe7ce41ca373b432382bd17d2ddac26..5767e19e8847d85481bdad0bb6813b9a226d9ad5 100644 (file)
@@ -54,6 +54,15 @@ vect_free_slp_tree (slp_tree node)
   FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
     vect_free_slp_tree (child);
 
+  gimple *stmt;
+  FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt)
+    /* After transform some stmts are removed and thus their vinfo is gone.  */
+    if (vinfo_for_stmt (stmt))
+      {
+       gcc_assert (STMT_VINFO_NUM_SLP_USES (vinfo_for_stmt (stmt)) > 0);
+       STMT_VINFO_NUM_SLP_USES (vinfo_for_stmt (stmt))--;
+      }
+
   SLP_TREE_CHILDREN (node).release ();
   SLP_TREE_SCALAR_STMTS (node).release ();
   SLP_TREE_VEC_STMTS (node).release ();
@@ -102,6 +111,10 @@ vect_create_new_slp_node (vec<gimple *> scalar_stmts)
   SLP_TREE_TWO_OPERATORS (node) = false;
   SLP_TREE_DEF_TYPE (node) = vect_internal_def;
 
+  unsigned i;
+  FOR_EACH_VEC_ELT (scalar_stmts, i, stmt)
+    STMT_VINFO_NUM_SLP_USES (vinfo_for_stmt (stmt))++;
+
   return node;
 }
 
@@ -401,6 +414,20 @@ again:
   /* Swap operands.  */
   if (swapped)
     {
+      /* If there are already uses of this stmt in a SLP instance then
+         we've committed to the operand order and can't swap it.  */
+      if (STMT_VINFO_NUM_SLP_USES (vinfo_for_stmt (stmt)) != 0)
+       {
+         if (dump_enabled_p ())
+           {
+             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                              "Build SLP failed: cannot swap operands of "
+                              "shared stmt ");
+             dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
+           }
+         return -1;
+       }
+
       if (first_op_cond)
        {
          tree cond = gimple_assign_rhs1 (stmt);
@@ -411,6 +438,12 @@ again:
       else
        swap_ssa_operands (stmt, gimple_assign_rhs1_ptr (stmt),
                           gimple_assign_rhs2_ptr (stmt));
+      if (dump_enabled_p ())
+       {
+         dump_printf_loc (MSG_NOTE, vect_location,
+                          "swapped operands to match def types in ");
+         dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
+       }
     }
 
   return 0;
@@ -1007,6 +1040,23 @@ vect_build_slp_tree (vec_info *vinfo,
             behavior.  */
          && *npermutes < 4)
        {
+         /* Verify if we can safely swap or if we committed to a specific
+            operand order already.  */
+         for (j = 0; j < group_size; ++j)
+           if (!matches[j]
+               && STMT_VINFO_NUM_SLP_USES (vinfo_for_stmt (stmts[j])) != 0)
+             {
+               if (dump_enabled_p ())
+                 {
+                   dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                                    "Build SLP failed: cannot swap operands "
+                                    "of shared stmt ");
+                   dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+                                     stmts[j], 0);
+                 }
+               goto fail;
+             }
+
          /* Swap mismatched definition stmts.  */
          dump_printf_loc (MSG_NOTE, vect_location,
                           "Re-trying with swapped operands of stmts ");
@@ -1095,6 +1145,7 @@ vect_build_slp_tree (vec_info *vinfo,
          ++*npermutes;
        }
 
+fail:
       gcc_assert (child == NULL);
       FOR_EACH_VEC_ELT (children, j, child)
        vect_free_slp_tree (child);
@@ -2186,18 +2237,21 @@ new_bb_vec_info (gimple_stmt_iterator region_begin,
 static void
 destroy_bb_vec_info (bb_vec_info bb_vinfo)
 {
-  vec<slp_instance> slp_instances;
   slp_instance instance;
-  basic_block bb;
-  gimple_stmt_iterator si;
   unsigned i;
 
   if (!bb_vinfo)
     return;
 
-  bb = BB_VINFO_BB (bb_vinfo);
+  vect_destroy_datarefs (bb_vinfo);
+  free_dependence_relations (BB_VINFO_DDRS (bb_vinfo));
+  BB_VINFO_GROUPED_STORES (bb_vinfo).release ();
+  FOR_EACH_VEC_ELT (BB_VINFO_SLP_INSTANCES (bb_vinfo), i, instance)
+    vect_free_slp_instance (instance);
+  BB_VINFO_SLP_INSTANCES (bb_vinfo).release ();
+  destroy_cost_data (BB_VINFO_TARGET_COST_DATA (bb_vinfo));
 
-  for (si = bb_vinfo->region_begin;
+  for (gimple_stmt_iterator si = bb_vinfo->region_begin;
        gsi_stmt (si) != gsi_stmt (bb_vinfo->region_end); gsi_next (&si))
     {
       gimple *stmt = gsi_stmt (si);
@@ -2211,16 +2265,8 @@ destroy_bb_vec_info (bb_vec_info bb_vinfo)
       gimple_set_uid (stmt, -1);
     }
 
-  vect_destroy_datarefs (bb_vinfo);
-  free_dependence_relations (BB_VINFO_DDRS (bb_vinfo));
-  BB_VINFO_GROUPED_STORES (bb_vinfo).release ();
-  slp_instances = BB_VINFO_SLP_INSTANCES (bb_vinfo);
-  FOR_EACH_VEC_ELT (slp_instances, i, instance)
-    vect_free_slp_instance (instance);
-  BB_VINFO_SLP_INSTANCES (bb_vinfo).release ();
-  destroy_cost_data (BB_VINFO_TARGET_COST_DATA (bb_vinfo));
+  BB_VINFO_BB (bb_vinfo)->aux = NULL;
   free (bb_vinfo);
-  bb->aux = NULL;
 }
 
 
index 872fa07664018862f7505a749fe137ad2fe60536..635c7970fca0f3b1e2e11225327b2ee14a088a7c 100644 (file)
@@ -8391,6 +8391,8 @@ new_stmt_vec_info (gimple *stmt, vec_info *vinfo)
 
   STMT_VINFO_SAME_ALIGN_REFS (res).create (0);
   STMT_SLP_TYPE (res) = loop_vect;
+  STMT_VINFO_NUM_SLP_USES (res) = 0;
+
   GROUP_FIRST_ELEMENT (res) = NULL;
   GROUP_NEXT_ELEMENT (res) = NULL;
   GROUP_SIZE (res) = 0;
index 1465070a0066f8d8b1809a69d736dfa1e41ce73f..0a3f5d75ffbae36c710ac7ce5f148095a7b6f9bd 100644 (file)
@@ -601,6 +601,8 @@ typedef struct _stmt_vec_info {
   /* For reduction loops, this is the type of reduction.  */
   enum vect_reduction_type v_reduc_type;
 
+  /* The number of scalar stmt references from active SLP instances.  */
+  unsigned int num_slp_uses;
 } *stmt_vec_info;
 
 /* Access Functions.  */
@@ -653,6 +655,7 @@ STMT_VINFO_BB_VINFO (stmt_vec_info stmt_vinfo)
 #define STMT_VINFO_LOOP_PHI_EVOLUTION_BASE_UNCHANGED(S) (S)->loop_phi_evolution_base_unchanged
 #define STMT_VINFO_LOOP_PHI_EVOLUTION_PART(S) (S)->loop_phi_evolution_part
 #define STMT_VINFO_MIN_NEG_DIST(S)     (S)->min_neg_dist
+#define STMT_VINFO_NUM_SLP_USES(S)     (S)->num_slp_uses
 
 #define GROUP_FIRST_ELEMENT(S)          (S)->first_element
 #define GROUP_NEXT_ELEMENT(S)           (S)->next_element