Bug 101340 - SLP discovery via vect_slp_linearize_chain is imperfect
Summary: SLP discovery via vect_slp_linearize_chain is imperfect
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 12.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Keywords: missed-optimization
Depends on:
Blocks: vectorizer
  Show dependency treegraph
Reported: 2021-07-06 10:52 UTC by Richard Biener
Modified: 2021-07-06 10:54 UTC (History)
0 users

See Also:
Known to work:
Known to fail:
Last reconfirmed:

testcase for the testsuite (1.09 KB, text/plain)
2021-07-06 10:52 UTC, Richard Biener

Note You need to log in before you can comment on or make changes to this bug.
Description Richard Biener 2021-07-06 10:52:05 UTC
For polyhedron capacita we have the hot fourir routine which with -ffast-math
suffers from reassoc perturbing the SLP lanes to not match.  SLP discovery
reassociation could help here but it's limited by the single_use check.

For loop vect we could allow uses outside of the chain but of course we
do not want to expand multi-uses inside.  That doesn't fit well with the
simple worklist approach but would need sth more elaborate.
Comment 1 Richard Biener 2021-07-06 10:52:51 UTC
Created attachment 51108 [details]
testcase for the testsuite
Comment 2 Richard Biener 2021-07-06 10:54:20 UTC
Patch that breaks for example gfortran.dg/PR100120.f90 because it expands
multi-uses inside a chain:

diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 2813b3dbe91..0c93be8e4d5 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -1491,7 +1491,11 @@ vect_slp_linearize_chain (vec_info *vinfo,
          gimple *use_stmt;
          use_operand_p use_p;
          if (dt == vect_internal_def
-             && single_imm_use (op, &use_p, &use_stmt)
+             /* For the loop SLP discovery case associate across multiple
+                uses as well, for BB vect avoid this since live lane
+                handling is not good enough yet.  */
+             && (is_a <loop_vec_info> (vinfo)
+                 || single_imm_use (op, &use_p, &use_stmt))
              && is_gimple_assign (def_stmt_info->stmt)
              && (gimple_assign_rhs_code (def_stmt_info->stmt) == code
                  || (code == PLUS_EXPR