This adjusts the SLP build to allow a pattern root stmt to be
built from scalars.  I've noticed this in PR98211 where we fail
to promote a SLP subtree to a simple splat operation and instead
emit a series of uniform vector operations.  The bb-slp-div-1.c
testcase is now vectorized on x86_64 but only the store so I
adjusted it to expect the load to be vectorized.

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

2020-12-10  Richard Biener  <rguent...@suse.de>

        * tree-vect-slp.c (vect_get_and_check_slp_defs): Do
        not mark the defs to occur in a pattern if it is the
        pattern root and record the original stmt defs in that
        case.

        * gcc.dg/vect/bb-slp-div-1.c: Expect the load to be
        vectorized.
---
 gcc/testsuite/gcc.dg/vect/bb-slp-div-1.c |  5 ++++-
 gcc/tree-vect-slp.c                      | 15 ++++++++++++---
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-div-1.c 
b/gcc/testsuite/gcc.dg/vect/bb-slp-div-1.c
index 87ffc9b897b..1eea9233b70 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-div-1.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-div-1.c
@@ -16,4 +16,7 @@ f (void)
   x[7] /= 9;
 }
 
-/* { dg-final { scan-tree-dump "optimized: basic block" "slp2" { xfail *-*-* } 
} } */
+/* We can vectorize the store from a CTOR built from scalar division
+   results but ideally we'd like to see vectorizing the load and the
+   division as well.  */
+/* { dg-final { scan-tree-dump "transform load" "slp2" { xfail *-*-* } } } */
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index d248ce2c3f7..e93e9c7a2d3 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -544,12 +544,21 @@ vect_get_and_check_slp_defs (vec_info *vinfo, unsigned 
char swap,
          continue;
        }
 
-      if (def_stmt_info && is_pattern_stmt_p (def_stmt_info))
-       oprnd_info->any_pattern = true;
-
       oprnd_info->def_stmts.quick_push (def_stmt_info);
       oprnd_info->ops.quick_push (oprnd);
 
+      if (def_stmt_info
+         && is_pattern_stmt_p (def_stmt_info))
+       {
+         if (STMT_VINFO_RELATED_STMT (vect_orig_stmt (def_stmt_info))
+             != def_stmt_info)
+           oprnd_info->any_pattern = true;
+         else
+           /* If we promote this to external use the original stmt def.  */
+           oprnd_info->ops.last ()
+             = gimple_get_lhs (vect_orig_stmt (def_stmt_info)->stmt);
+       }
+
       /* If there's a extern def on a backedge make sure we can
         code-generate at the region start.
         ???  This is another case that could be fixed by adjusting
-- 
2.26.2

Reply via email to