Include phis in SLP unrolling calculation
authorRichard Sandiford <richard.sandiford@linaro.org>
Mon, 18 Sep 2017 15:39:21 +0000 (15:39 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Mon, 18 Sep 2017 15:39:21 +0000 (15:39 +0000)
Without this we'd pick an unrolling factor based purely on longs,
ignoring the ints.  It's posssible that vect_get_smallest_scalar_type
should also handle shifts, but I think we'd still want this as a
belt-and-braces fix.

2017-09-18  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
* tree-vect-slp.c (vect_record_max_nunits): New function,
split out from...
(vect_build_slp_tree_1): ...here.
(vect_build_slp_tree_2): Call it for phis too.

gcc/testsuite/
* gcc.dg/vect/slp-multitypes-13.c: New test.

From-SVN: r252933

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

index 70b73509c4ef7f48d5cbd16ffa4d0ae0248a7212..130793eaf5a0c28cfe3728ed514fbcee0641b0ec 100644 (file)
@@ -1,3 +1,10 @@
+2017-09-18  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * tree-vect-slp.c (vect_record_max_nunits): New function,
+       split out from...
+       (vect_build_slp_tree_1): ...here.
+       (vect_build_slp_tree_2): Call it for phis too.
+
 2017-09-18  Richard Sandiford  <richard.sandiford@linaro.org>
 
        * tree-vect-stmts.c (vectorizable_mask_load_store): Pass mask_vectype
index a4662844f8450f142a48530eadff4d25be560fd2..c0de42aa5a60cdea005d50064880e3394cb4f012 100644 (file)
@@ -1,3 +1,7 @@
+2017-09-18  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * gcc.dg/vect/slp-multitypes-13.c: New test.
+
 2017-09-18  Richard Sandiford  <richard.sandiford@linaro.org>
 
        * gfortran.dg/vect/mask-store-1.f90: New test.
diff --git a/gcc/testsuite/gcc.dg/vect/slp-multitypes-13.c b/gcc/testsuite/gcc.dg/vect/slp-multitypes-13.c
new file mode 100644 (file)
index 0000000..bbbbb2c
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+
+void
+f (long *x, int n)
+{
+  for (int i = 0; i < n; i++)
+    {
+      x[i * 2] = 1L << i;
+      x[i * 2 + 1] = 1L << i;
+    }
+}
index 32174fe6bb02f187897553ecde73b4a07c4432b3..0168f8bdeb8d962f51379aff3be8848074f23dd9 100644 (file)
@@ -480,6 +480,48 @@ again:
   return 0;
 }
 
+/* A subroutine of vect_build_slp_tree for checking VECTYPE, which is the
+   caller's attempt to find the vector type in STMT with the narrowest
+   element type.  Return true if VECTYPE is nonnull and if it is valid
+   for VINFO.  When returning true, update MAX_NUNITS to reflect the
+   number of units in VECTYPE.  VINFO, GORUP_SIZE and MAX_NUNITS are
+   as for vect_build_slp_tree.  */
+
+static bool
+vect_record_max_nunits (vec_info *vinfo, gimple *stmt, unsigned int group_size,
+                       tree vectype, unsigned int *max_nunits)
+{
+  if (!vectype)
+    {
+      if (dump_enabled_p ())
+       {
+         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                          "Build SLP failed: unsupported data-type in ");
+         dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
+         dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
+       }
+      /* Fatal mismatch.  */
+      return false;
+    }
+
+  /* If populating the vector type requires unrolling then fail
+     before adjusting *max_nunits for basic-block vectorization.  */
+  if (is_a <bb_vec_info> (vinfo)
+      && TYPE_VECTOR_SUBPARTS (vectype) > group_size)
+    {
+      dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                      "Build SLP failed: unrolling required "
+                      "in basic block SLP\n");
+      /* Fatal mismatch.  */
+      return false;
+    }
+
+  /* In case of multiple types we need to detect the smallest type.  */
+  if (*max_nunits < TYPE_VECTOR_SUBPARTS (vectype))
+    *max_nunits = TYPE_VECTOR_SUBPARTS (vectype);
+
+  return true;
+}
 
 /* Verify if the scalar stmts STMTS are isomorphic, require data
    permutation or are of unsupported types of operation.  Return
@@ -560,38 +602,14 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
 
       scalar_type = vect_get_smallest_scalar_type (stmt, &dummy, &dummy);
       vectype = get_vectype_for_scalar_type (scalar_type);
-      if (!vectype)
-        {
-          if (dump_enabled_p ())
-            {
-              dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 
-                              "Build SLP failed: unsupported data-type ");
-              dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
-                                scalar_type);
-              dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
-            }
+      if (!vect_record_max_nunits (vinfo, stmt, group_size, vectype,
+                                  max_nunits))
+       {
          /* Fatal mismatch.  */
          matches[0] = false;
           return false;
         }
 
-      /* If populating the vector type requires unrolling then fail
-         before adjusting *max_nunits for basic-block vectorization.  */
-      if (is_a <bb_vec_info> (vinfo)
-         && TYPE_VECTOR_SUBPARTS (vectype) > group_size)
-       {
-         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 
-                          "Build SLP failed: unrolling required "
-                          "in basic block SLP\n");
-         /* Fatal mismatch.  */
-         matches[0] = false;
-         return false;
-       }
-
-      /* In case of multiple types we need to detect the smallest type.  */
-      if (*max_nunits < TYPE_VECTOR_SUBPARTS (vectype))
-       *max_nunits = TYPE_VECTOR_SUBPARTS (vectype);
-
       if (gcall *call_stmt = dyn_cast <gcall *> (stmt))
        {
          rhs_code = CALL_EXPR;
@@ -1018,6 +1036,12 @@ vect_build_slp_tree_2 (vec_info *vinfo,
      the recursion.  */
   if (gimple_code (stmt) == GIMPLE_PHI)
     {
+      tree scalar_type = TREE_TYPE (PHI_RESULT (stmt));
+      tree vectype = get_vectype_for_scalar_type (scalar_type);
+      if (!vect_record_max_nunits (vinfo, stmt, group_size, vectype,
+                                  max_nunits))
+       return NULL;
+
       vect_def_type def_type = STMT_VINFO_DEF_TYPE (vinfo_for_stmt (stmt));
       /* Induction from different IVs is not supported.  */
       if (def_type == vect_induction_def)