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-10-24  Richard Sandiford  <richard.sandif...@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.

Index: gcc/tree-vect-stmts.c
===================================================================
--- gcc/tree-vect-stmts.c       2019-10-25 13:27:26.205687511 +0100
+++ gcc/tree-vect-stmts.c       2019-10-25 13:27:32.877640367 +0100
@@ -11973,7 +11973,12 @@ vect_get_vector_types_for_stmt (stmt_vec
   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));
@@ -12005,7 +12010,7 @@ vect_get_vector_types_for_stmt (stmt_vec
 
       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,
@@ -12022,42 +12027,38 @@ vect_get_vector_types_for_stmt (stmt_vec
 
   /* 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");

Reply via email to