Allow mixed vector sizes within a single vectorised stmt
authorRichard Sandiford <richard.sandiford@arm.com>
Thu, 14 Nov 2019 15:16:40 +0000 (15:16 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 14 Nov 2019 15:16:40 +0000 (15:16 +0000)
Although a previous patch allowed mixed vector sizes within a vector
region, we generally still required equal vector sizes within a vector
stmt.  Specifically, vect_get_vector_types_for_stmt computes two vector
types: the vector type corresponding to STMT_VINFO_VECTYPE and the
vector type that determines the minimum vectorisation factor for the
stmt ("nunits_vectype").  It then required these two types to be
the same size.

There doesn't seem to be any need for that restriction though.  AFAICT,
all vectorizable_* functions either do their own compatibility checks
or don't need to do them (because gimple guarantees that the scalar
types are compatible).

It should always be the case that nunits_vectype has at least as many
elements as the other vectype, but that's something we can assert for.

I couldn't resist a couple of other tweaks while there:

- there's no need to compute nunits_vectype if its element type is
  the same as STMT_VINFO_VECTYPE's.

- it's useful to distinguish the nunits_vectype from the main vectype
  in dump messages

- when reusing the existing STMT_VINFO_VECTYPE, it's useful to say so
  in the dump, and say what the type is

2019-11-14  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
* tree-vect-stmts.c (vect_get_vector_types_for_stmt): Don't
require vectype and nunits_vectype to have the same size;
instead assert that nunits_vectype has at least as many
elements as vectype.  Don't compute a separate nunits_vectype
if the scalar type is obviously the same as vectype's.
Tweak dump messages.

From-SVN: r278244

gcc/ChangeLog
gcc/tree-vect-stmts.c

index 7515ee1..6bb0a80 100644 (file)
@@ -1,5 +1,14 @@
 2019-11-14  Richard Sandiford  <richard.sandiford@arm.com>
 
+       * tree-vect-stmts.c (vect_get_vector_types_for_stmt): Don't
+       require vectype and nunits_vectype to have the same size;
+       instead assert that nunits_vectype has at least as many
+       elements as vectype.  Don't compute a separate nunits_vectype
+       if the scalar type is obviously the same as vectype's.
+       Tweak dump messages.
+
+2019-11-14  Richard Sandiford  <richard.sandiford@arm.com>
+
        * config/aarch64/aarch64.c (aarch64_vectorize_related_mode): New
        function.
        (aarch64_autovectorize_vector_modes): Also add V4HImode and V2SImode.
index e1fa075..5f30d1e 100644 (file)
@@ -12018,7 +12018,12 @@ vect_get_vector_types_for_stmt (stmt_vec_info stmt_info,
   tree vectype;
   tree scalar_type = NULL_TREE;
   if (STMT_VINFO_VECTYPE (stmt_info))
-    *stmt_vectype_out = vectype = STMT_VINFO_VECTYPE (stmt_info);
+    {
+      *stmt_vectype_out = vectype = STMT_VINFO_VECTYPE (stmt_info);
+      if (dump_enabled_p ())
+       dump_printf_loc (MSG_NOTE, vect_location,
+                        "precomputed vectype: %T\n", vectype);
+    }
   else
     {
       gcc_assert (!STMT_VINFO_DATA_REF (stmt_info));
@@ -12050,7 +12055,7 @@ vect_get_vector_types_for_stmt (stmt_vec_info stmt_info,
 
       if (dump_enabled_p ())
        dump_printf_loc (MSG_NOTE, vect_location,
-                        "get vectype for scalar type:  %T\n", scalar_type);
+                        "get vectype for scalar type: %T\n", scalar_type);
       vectype = get_vectype_for_scalar_type (vinfo, scalar_type);
       if (!vectype)
        return opt_result::failure_at (stmt,
@@ -12067,42 +12072,38 @@ vect_get_vector_types_for_stmt (stmt_vec_info stmt_info,
 
   /* Don't try to compute scalar types if the stmt produces a boolean
      vector; use the existing vector type instead.  */
-  tree nunits_vectype;
-  if (VECTOR_BOOLEAN_TYPE_P (vectype))
-    nunits_vectype = vectype;
-  else
+  tree nunits_vectype = vectype;
+  if (!VECTOR_BOOLEAN_TYPE_P (vectype)
+      && *stmt_vectype_out != boolean_type_node)
     {
       /* The number of units is set according to the smallest scalar
         type (or the largest vector size, but we only support one
         vector size per vectorization).  */
-      if (*stmt_vectype_out != boolean_type_node)
+      HOST_WIDE_INT dummy;
+      scalar_type = vect_get_smallest_scalar_type (stmt_info, &dummy, &dummy);
+      if (scalar_type != TREE_TYPE (vectype))
        {
-         HOST_WIDE_INT dummy;
-         scalar_type = vect_get_smallest_scalar_type (stmt_info,
-                                                      &dummy, &dummy);
+         if (dump_enabled_p ())
+           dump_printf_loc (MSG_NOTE, vect_location,
+                            "get vectype for smallest scalar type: %T\n",
+                            scalar_type);
+         nunits_vectype = get_vectype_for_scalar_type (vinfo, scalar_type);
+         if (!nunits_vectype)
+           return opt_result::failure_at
+             (stmt, "not vectorized: unsupported data-type %T\n",
+              scalar_type);
+         if (dump_enabled_p ())
+           dump_printf_loc (MSG_NOTE, vect_location, "nunits vectype: %T\n",
+                            nunits_vectype);
        }
-      if (dump_enabled_p ())
-       dump_printf_loc (MSG_NOTE, vect_location,
-                        "get vectype for scalar type:  %T\n", scalar_type);
-      nunits_vectype = get_vectype_for_scalar_type (vinfo, scalar_type);
     }
-  if (!nunits_vectype)
-    return opt_result::failure_at (stmt,
-                                  "not vectorized: unsupported data-type %T\n",
-                                  scalar_type);
 
-  if (maybe_ne (GET_MODE_SIZE (TYPE_MODE (vectype)),
-               GET_MODE_SIZE (TYPE_MODE (nunits_vectype))))
-    return opt_result::failure_at (stmt,
-                                  "not vectorized: different sized vector "
-                                  "types in statement, %T and %T\n",
-                                  vectype, nunits_vectype);
+  gcc_assert (*stmt_vectype_out == boolean_type_node
+             || multiple_p (TYPE_VECTOR_SUBPARTS (nunits_vectype),
+                            TYPE_VECTOR_SUBPARTS (*stmt_vectype_out)));
 
   if (dump_enabled_p ())
     {
-      dump_printf_loc (MSG_NOTE, vect_location, "vectype: %T\n",
-                      nunits_vectype);
-
       dump_printf_loc (MSG_NOTE, vect_location, "nunits = ");
       dump_dec (MSG_NOTE, TYPE_VECTOR_SUBPARTS (nunits_vectype));
       dump_printf (MSG_NOTE, "\n");