When we split an irreducible region for BB vectorization analysis
the defensive handling of external backedge defs in
vect_get_and_check_slp_defs doesn't work since that relies on
dominance info to identify a backedge. The testcase also shows
we are iterating over the function in a sub-optimal way which is
why we split the irreducible region in the first place. The fix
is to mark backedges and use EDGE_DFS_BACK to identify them.
This is a simplified variant of the fix that went to trunk in GCC 14
times, avoiding to change the iteration order we gather BBs for
BB vectorization. We're now hitting the bug on the branch when
building haproxy with LTO on ppc64le and s390x, this should be
a safe patch.
Bootstrap and regtest running on x86_64-unknown-linux-gnu.
PR tree-optimization/111387
* tree-vect-slp.cc (vect_get_and_check_slp_defs): Check
EDGE_DFS_BACK when doing BB vectorization.
(vect_slp_function): Mark backedges.
* gcc.dg/torture/pr111387.c: New testcase.
---
gcc/testsuite/gcc.dg/torture/pr111387.c | 34 +++++++++++++++++++++++++
gcc/tree-vect-slp.cc | 11 +++++---
2 files changed, 42 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/torture/pr111387.c
diff --git a/gcc/testsuite/gcc.dg/torture/pr111387.c
b/gcc/testsuite/gcc.dg/torture/pr111387.c
new file mode 100644
index 00000000000..e14eeef6e4a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr111387.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-ftree-vectorize -fno-vect-cost-model" } */
+
+struct {
+ unsigned a;
+ unsigned b;
+} c;
+int d, e, f, g, h;
+int main()
+{
+ if (c.b && g && g > 7)
+ goto i;
+ j:
+ if (c.a) {
+ int k = 0;
+ unsigned l = c.b;
+ if (0) {
+ m:
+ k = l = c.b;
+ }
+ c.a = k;
+ c.b = l;
+ }
+ if (0) {
+ i:
+ goto m;
+ }
+ if (d)
+ goto j;
+ for (f = 5; f; f--)
+ if (h)
+ e = 0;
+ return 0;
+}
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index d5b114dbcc9..19050c2c164 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -594,9 +594,13 @@ vect_get_and_check_slp_defs (vec_info *vinfo, unsigned
char swap,
{
oprnd = gimple_arg (stmt_info->stmt, opno);
if (gphi *stmt = dyn_cast <gphi *> (stmt_info->stmt))
- backedge = dominated_by_p (CDI_DOMINATORS,
- gimple_phi_arg_edge (stmt, opno)->src,
- gimple_bb (stmt_info->stmt));
+ {
+ edge e = gimple_phi_arg_edge (stmt, opno);
+ backedge = (is_a <bb_vec_info> (vinfo)
+ ? e->flags & EDGE_DFS_BACK
+ : dominated_by_p (CDI_DOMINATORS, e->src,
+ gimple_bb (stmt_info->stmt)));
+ }
}
if (TREE_CODE (oprnd) == VIEW_CONVERT_EXPR)
oprnd = TREE_OPERAND (oprnd, 0);
@@ -7678,6 +7682,7 @@ vect_slp_function (function *fun)
bool r = false;
int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fun));
unsigned n = pre_and_rev_post_order_compute_fn (fun, NULL, rpo, false);
+ mark_dfs_back_edges (fun);
/* For the moment split the function into pieces to avoid making
the iteration on the vector mode moot. Split at points we know
--
2.51.0