The testcase shows both live lane extraction and (reduction) root
schedule verification errorneously allow the use/root stmt to be
the same as the placement point. But as we insert vector defs
after the placement point we have to exclude it.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.
PR tree-optimization/126936
* tree-vect-slp.cc (vect_bb_slp_mark_live_stmts): Exclude
use_stmt from dominance check.
(vect_schedule_slp): Likewise for root.
* gcc.dg/vect/bb-slp-pr126936.c: New testcase.
---
gcc/testsuite/gcc.dg/vect/bb-slp-pr126936.c | 142 ++++++++++++++++++++
gcc/tree-vect-slp.cc | 12 +-
2 files changed, 151 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-pr126936.c
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr126936.c
b/gcc/testsuite/gcc.dg/vect/bb-slp-pr126936.c
new file mode 100644
index 00000000000..a5683f0abf1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr126936.c
@@ -0,0 +1,142 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fgimple" } */
+
+void foo(int);
+
+int *c;
+char d;
+
+void __GIMPLE (ssa,guessed_local(63136016),startwith("slp"))
+fn1 ()
+{
+ int * _1;
+ int _2;
+ char _9;
+ int _12;
+ int _17;
+ int _32;
+ unsigned int _33;
+ int _35;
+ int _36;
+ unsigned int _37;
+ unsigned int _38;
+ int _39;
+ unsigned int _47;
+ int _48;
+ int * _49;
+ int * _54;
+ int _55;
+ unsigned int _56;
+ unsigned int _57;
+ int _58;
+ int _59;
+ int * _70;
+ int _71;
+ unsigned int _72;
+ unsigned int _73;
+ int _74;
+ int _75;
+ int * _86;
+ int _87;
+ unsigned int _88;
+ unsigned int _89;
+ int _90;
+ int _91;
+ int * _102;
+ int _103;
+ unsigned int _104;
+ unsigned int _105;
+ int _106;
+ int _107;
+ int * _118;
+ int _119;
+ unsigned int _120;
+ unsigned int _121;
+ int _122;
+ int _123;
+ unsigned int _136;
+ unsigned int _137;
+ int _138;
+ int _139;
+ unsigned int _152;
+ unsigned int _153;
+ int _154;
+ int _155;
+ int _171;
+ int _187;
+ int _203;
+ int _219;
+ int _235;
+ int _251;
+
+ __BB(2,guessed_local(63136016)):
+ _1 = c;
+ _2 = __MEM <int> (_1 + _Literal (int *) 56);
+ foo (_2);
+ _39 = __MEM <int> (_1);
+ _38 = (unsigned int) _39;
+ _37 = _38 % 3u;
+ _36 = (int) _37;
+ _35 = _36 & _39;
+ __MEM <int> (_1) = _35;
+ _49 = _1 + 8ul;
+ _48 = __MEM <int> (_49);
+ _47 = (unsigned int) _48;
+ _33 = _47 % 3u;
+ _32 = (int) _33;
+ _17 = _32 & _35;
+ __MEM <int> (_1) = _17;
+ _54 = _1 + 16ul;
+ _55 = __MEM <int> (_54);
+ _56 = (unsigned int) _55;
+ _57 = _56 % 3u;
+ _58 = (int) _57;
+ _59 = _17 & _58;
+ __MEM <int> (_1) = _59;
+ _70 = _1 + 24ul;
+ _71 = __MEM <int> (_70);
+ _72 = (unsigned int) _71;
+ _73 = _72 % 3u;
+ _74 = (int) _73;
+ _75 = _59 & _74;
+ __MEM <int> (_1) = _75;
+ _86 = _1 + 32ul;
+ _87 = __MEM <int> (_86);
+ _88 = (unsigned int) _87;
+ _89 = _88 % 3u;
+ _90 = (int) _89;
+ _91 = _75 & _90;
+ __MEM <int> (_1) = _91;
+ _102 = _1 + 40ul;
+ _103 = __MEM <int> (_102);
+ _104 = (unsigned int) _103;
+ _105 = _104 % 3u;
+ _106 = (int) _105;
+ _107 = _91 & _106;
+ __MEM <int> (_1) = _107;
+ _118 = _1 + 48ul;
+ _119 = __MEM <int> (_118);
+ _120 = (unsigned int) _119;
+ _121 = _120 % 3u;
+ _122 = (int) _121;
+ _123 = _107 & _122;
+ _136 = (unsigned int) _2;
+ _137 = _136 % 3u;
+ _138 = (int) _137;
+ _139 = _123 & _138;
+ _152 = (unsigned int) _139;
+ _153 = _152 % 3u;
+ _154 = (int) _153;
+ _155 = _139 & _154;
+ _171 = _32 & _155;
+ _187 = _58 & _171;
+ _203 = _74 & _187;
+ _219 = _90 & _203;
+ _235 = _106 & _219;
+ _251 = _122 & _235;
+ _12 = _138 & _251;
+ __MEM <int> (_1) = _12;
+ _9 = (char) _137;
+ d = _9;
+ return;
+}
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index d0692b088c1..e7aff6565bf 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -9400,7 +9400,10 @@ vect_bb_slp_mark_live_stmts (bb_vec_info bb_vinfo,
slp_tree node,
gimple_bb (last_stmt)))
can_insert = false;
}
- else if (!vect_stmt_dominates_stmt_p (last_stmt, use_stmt))
+ /* As we instert after last_stmt it may not be the use_stmt
+ itself. */
+ else if (last_stmt == use_stmt
+ || !vect_stmt_dominates_stmt_p (last_stmt, use_stmt))
can_insert = false;
if (!can_insert)
{
@@ -12924,8 +12927,11 @@ vect_schedule_slp (vec_info *vinfo, vec<slp_instance>
&slp_instances,
if (place_only)
{
gimple *root_stmt = instance->root_stmts[0]->stmt;
- res &= (!node->si || vect_stmt_dominates_stmt_p (node->si,
- root_stmt));
+ res &= (!node->si
+ /* As we instert after node->si it may not be the
+ root_stmt itself. */
+ || (node->si != root_stmt
+ && vect_stmt_dominates_stmt_p (node->si, root_stmt)));
}
else
vectorize_slp_instance_root_stmt (vinfo, node, instance);
--
2.51.0