When scheduling the SLP graph we fail to cache a scheduling result,
so when there's multiple entries referencing a failed node we
realize we have visited it already but fail to re-instantiate a
failure to schedule.

Bootstrapped and tested on x86_64-unknown-linux-gnu and
aarch64-linux-gnu, pushed.

        PR tree-optimization/127018
        * tree-vect-slp.cc (slp_scc_info::res): New member.
        (vect_schedule_scc): Initialize res for invariants
        and when pushing to the stack.  Record result for
        singletons and look it up for already visited entries.

        * gcc.dg/vect/bb-slp-pr127018.c: New testcase.
---
 gcc/testsuite/gcc.dg/vect/bb-slp-pr127018.c | 80 +++++++++++++++++++++
 gcc/tree-vect-slp.cc                        |  8 ++-
 2 files changed, 87 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-pr127018.c

diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr127018.c 
b/gcc/testsuite/gcc.dg/vect/bb-slp-pr127018.c
new file mode 100644
index 00000000000..bc85c841cd8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr127018.c
@@ -0,0 +1,80 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fgimple" } */
+/* { dg-additional-options "-msse4" { target sse4 } } */
+
+char* mm;
+char m;
+
+void __GIMPLE (ssa,guessed_local(1073741822),startwith("slp"))
+decode_endpoint (int * pEndpoints, int index)
+{
+  int tt;
+  int t;
+  int y1;
+  int v3;
+  int v1;
+  int v0;
+  char _1;
+  char * _2;
+  char _3;
+  char _4;
+
+  __BB(2,guessed_local(1073741822)):
+  if (index_8(D) == 0)
+    goto __BB9(guessed(45634028));
+  else
+    goto __BB3(guessed(88583700));
+
+  __BB(9,guessed_local(365072223)):
+  goto __BB8(precise(134217728));
+
+  __BB(3,guessed_local(708669599)):
+  _1 = m;
+  v0_10 = (int) _1;
+  _2 = mm;
+  _3 = __MEM <char> (_2 + _Literal (char *) 1);
+  v1_11 = (int) _3;
+  if (index_8(D) == 3)
+    goto __BB4(guessed(45634028));
+  else
+    goto __BB5(guessed(88583700));
+
+  __BB(4,guessed_local(240947666)):
+  _4 = __MEM <char> (_2 + _Literal (char *) 3);
+  v3_20 = (int) _4;
+  __MEM <int[2]> (pEndpoints_15(D) + _Literal (int *) 16)[0] = v0_10;
+  __MEM <int[2]> (pEndpoints_15(D) + _Literal (int *) 16)[1] = v1_11;
+  __MEM <int[2]> (pEndpoints_15(D) + _Literal (int *) 24)[1] = v3_20;
+  __MEM <int[2]> (pEndpoints_15(D) + _Literal (int *) 24)[0] = v3_20;
+  goto __BB8(precise(134217728));
+
+  __BB(5,guessed_local(467721933)):
+  t_12 = v0_10 << 4;
+  tt_13 = v1_11 << 4;
+  if (v0_10 <= v1_11)
+    goto __BB10(guessed(67108864));
+  else
+    goto __BB6(guessed(67108864));
+
+  __BB(10,guessed_local(233860967)):
+  goto __BB7(precise(134217728));
+
+  __BB(6,guessed_local(233860966)):
+  t_14 = t_12 + tt_13;
+  goto __BB7(precise(134217728));
+
+  __BB(7,guessed_local(467721933)):
+  y1_5 = __PHI (__BB10: tt_13, __BB6: 0);
+  t_6 = __PHI (__BB10: t_12, __BB6: t_14);
+  __MEM <int[2]> (pEndpoints_15(D))[0] = t_6;
+  __MEM <int[2]> (pEndpoints_15(D))[1] = y1_5;
+  __MEM <int[2]> (pEndpoints_15(D) + _Literal (int *) 16)[0] = t_6;
+  __MEM <int[2]> (pEndpoints_15(D) + _Literal (int *) 16)[1] = y1_5;
+  goto __BB8(precise(134217728));
+
+  __BB(8,guessed_local(1073741824)):
+  return;
+
+}
+
+
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index 4ef1f7b91b1..0ee1c1cc311 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -12513,6 +12513,7 @@ vectorize_slp_instance_root_stmt (vec_info *vinfo, 
slp_tree node, slp_instance i
 struct slp_scc_info
 {
   bool on_stack;
+  bool res;
   int dfs;
   int lowlink;
 };
@@ -12538,10 +12539,12 @@ vect_schedule_scc (vec_info *vinfo, slp_tree node, 
slp_instance instance,
       info->on_stack = false;
       bool res = vect_schedule_slp_node (vinfo, node, instance, place_only);
       gcc_assert (res);
-      return true;
+      info->res = res;
+      return res;
     }
 
   info->on_stack = true;
+  info->res = true;
   stack.safe_push (node);
 
   bool res = true;
@@ -12564,6 +12567,8 @@ vect_schedule_scc (vec_info *vinfo, slp_tree node, 
slp_instance instance,
        }
       else if (child_info->on_stack)
        info->lowlink = MIN (info->lowlink, child_info->dfs);
+      else
+       res &= child_info->res;
     }
   if (info->lowlink != info->dfs)
     return res;
@@ -12576,6 +12581,7 @@ vect_schedule_scc (vec_info *vinfo, slp_tree node, 
slp_instance instance,
       stack.pop ();
       info->on_stack = false;
       res &= vect_schedule_slp_node (vinfo, node, instance, place_only);
+      info->res = res;
       if (!SLP_TREE_PERMUTE_P (node)
          && is_a <gphi *> (SLP_TREE_REPRESENTATIVE (node)->stmt))
        phis_to_fixup.quick_push (node);
-- 
2.51.0

Reply via email to