Avoid uniform lane BB vectorization
authorRichard Biener <rguenther@suse.de>
Tue, 27 Oct 2020 10:03:27 +0000 (11:03 +0100)
committerRichard Biener <rguenther@suse.de>
Tue, 27 Oct 2020 12:16:35 +0000 (13:16 +0100)
This makes sure to use splats early when facing uniform internal
operands in BB SLP discovery rather than relying on the late
heuristincs re-building nodes from scratch.

2020-10-27  Richard Biener  <rguenther@suse.de>

* tree-vect-slp.c (vect_build_slp_tree_2): When vectorizing
BBs splat uniform operands and stop SLP discovery.

* gcc.target/i386/pr95866-1.c: Adjust.

gcc/testsuite/gcc.target/i386/pr95866-1.c
gcc/tree-vect-slp.c

index 991370cf669e459f2471b2ce1212acb51fdf8fe6..553d415eed82c238ba318d91ec40c72585b6e8a1 100644 (file)
@@ -13,6 +13,6 @@ void foo(int i)
 
 /* We should not use vector operations for i + 1 and (i + 1) & 31 but
    instead use { j, j, j, j }.  */ 
-/* { dg-final { scan-tree-dump-times "Building parent vector operands from scalars" 2 "slp2" } } */
+/* { dg-final { scan-tree-dump-times "Using a splat of the uniform operand" 2 "slp2" } } */
 /* { dg-final { scan-tree-dump-not " = \{i_" "slp2" } } */
 /* { dg-final { scan-tree-dump-times " = \{j_" 1 "slp2" } } */
index 894f045c0fe6a97d620119140cfd29dd62605426..85865dae1ab0d00046e77284bbb0328313ef1884 100644 (file)
@@ -1486,6 +1486,28 @@ vect_build_slp_tree_2 (vec_info *vinfo,
          continue;
        }
 
+      if (is_a <bb_vec_info> (vinfo)
+         && oprnd_info->first_dt == vect_internal_def)
+       {
+         /* For BB vectorization, if all defs are the same do not
+            bother to continue the build along the single-lane
+            graph but use a splat of the scalar value.  */
+         stmt_vec_info first_def = oprnd_info->def_stmts[0];
+         for (j = 1; j < group_size; ++j)
+           if (oprnd_info->def_stmts[j] != first_def)
+             break;
+         if (j == group_size
+             /* But avoid doing this for loads where we may be
+                able to CSE things.  */
+             && !gimple_vuse (first_def->stmt))
+           {
+             if (dump_enabled_p ())
+               dump_printf_loc (MSG_NOTE, vect_location,
+                                "Using a splat of the uniform operand\n");
+             oprnd_info->first_dt = vect_external_def;
+           }
+       }
+
       if (oprnd_info->first_dt != vect_internal_def
          && oprnd_info->first_dt != vect_reduction_def
          && oprnd_info->first_dt != vect_induction_def)