tree-optimization/95770 - fix SLP vectorized stmt placement compute
authorRichard Biener <rguenther@suse.de>
Mon, 22 Jun 2020 10:14:54 +0000 (12:14 +0200)
committerRichard Biener <rguenther@suse.de>
Mon, 22 Jun 2020 10:17:41 +0000 (12:17 +0200)
This fixes the vectorized stmt placement compute for the case of
external defs.

2020-06-22  Richard Biener  <rguenther@suse.de>

PR tree-optimization/95770
* tree-vect-slp.c (vect_schedule_slp_instance): Also consider
external defs.

* gcc.dg/pr95770.c: New testcase.

gcc/testsuite/gcc.dg/pr95770.c [new file with mode: 0644]
gcc/tree-vect-slp.c

diff --git a/gcc/testsuite/gcc.dg/pr95770.c b/gcc/testsuite/gcc.dg/pr95770.c
new file mode 100644 (file)
index 0000000..06714ea
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+float *a;
+void b(float c, float d)
+{
+  a[0] = a[1] = 0.5f * (c - 2 + d);
+  a[2] = a[3] = 0.5f * (c + 2 + d);
+}
index 5c169f37022b27c462a4f39f47eed11f30e5ad19..4031db4a9c6f91cf89849f2e29e8d08750cbeeca 100644 (file)
@@ -4216,9 +4216,6 @@ vect_schedule_slp_instance (vec_info *vinfo,
         children vectorized defs.  */
       gimple *last_stmt = NULL;
       FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
-       /* ???  With only external defs the following breaks.  Note
-          external defs do not get all vector init stmts generated
-          at the same place.  */
        if (SLP_TREE_DEF_TYPE (child) == vect_internal_def)
          {
            /* We are emitting all vectorized stmts in the same place and
@@ -4232,6 +4229,21 @@ vect_schedule_slp_instance (vec_info *vinfo,
                  || vect_stmt_dominates_stmt_p (last_stmt, vstmt))
                last_stmt = vstmt;
          }
+       else
+         {
+           /* For externals we have to look at all defs since their
+              insertion place is decided per vector.  */
+           unsigned j;
+           tree vdef;
+           FOR_EACH_VEC_ELT (SLP_TREE_VEC_DEFS (child), j, vdef)
+             if (TREE_CODE (vdef) == SSA_NAME)
+               {
+                 gimple *vstmt = SSA_NAME_DEF_STMT (vdef);
+                 if (!last_stmt
+                     || vect_stmt_dominates_stmt_p (last_stmt, vstmt))
+                   last_stmt = vstmt;
+               }
+         }
       if (is_a <gphi *> (last_stmt))
        si = gsi_after_labels (gimple_bb (last_stmt));
       else