vect: Allow vconds between different vector sizes
authorRichard Sandiford <richard.sandiford@arm.com>
Wed, 11 Nov 2020 11:42:45 +0000 (11:42 +0000)
committerRichard Sandiford <richard.sandiford@arm.com>
Wed, 11 Nov 2020 11:42:45 +0000 (11:42 +0000)
The vcond code requires the compared vectors and the selected
vectors to have both the same size and the same number of elements
as each other.  But the operation makes logical sense even for
different vector sizes.  E.g. you could compare two V4SIs and
use the result to select between two V4DIs.

The underlying optab already allows the compared mode and the selected
mode to be specified separately.  Since the vectoriser now also
supports mixed vector sizes, I think we can simply remove the
equal-size check and just keep the equal-lanes check.  It's then
up to the target to decide which (if any) mixtures of sizes it
supports.

gcc/
* optabs-tree.c (expand_vec_cond_expr_p): Allow the compared values
and the selected values to have different mode sizes.
* gimple-isel.cc (gimple_expand_vec_cond_expr): Likewise.

gcc/gimple-isel.cc
gcc/optabs-tree.c

index 9186ff55cdd9a3a6d2884567ee8e6f8c22df15e9..b5362cc4b01947b3254dbcfdbd1a00354ae126d0 100644 (file)
@@ -199,9 +199,8 @@ gimple_expand_vec_cond_expr (gimple_stmt_iterator *gsi,
   unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
 
 
-  gcc_assert (known_eq (GET_MODE_SIZE (mode), GET_MODE_SIZE (cmp_op_mode))
-             && known_eq (GET_MODE_NUNITS (mode),
-                          GET_MODE_NUNITS (cmp_op_mode)));
+  gcc_assert (known_eq (GET_MODE_NUNITS (mode),
+                       GET_MODE_NUNITS (cmp_op_mode)));
 
   icode = get_vcond_icode (mode, cmp_op_mode, unsignedp);
   if (icode == CODE_FOR_nothing)
index badd30bfda8dcf385a7c05f31ccba4834dabc825..4dfda756932de1693667c39c6fabed043b20b63b 100644 (file)
@@ -377,8 +377,7 @@ expand_vec_cond_expr_p (tree value_type, tree cmp_op_type, enum tree_code code)
                               TYPE_MODE (cmp_op_type)) != CODE_FOR_nothing)
     return true;
 
-  if (maybe_ne (GET_MODE_SIZE (value_mode), GET_MODE_SIZE (cmp_op_mode))
-      || maybe_ne (GET_MODE_NUNITS (value_mode), GET_MODE_NUNITS (cmp_op_mode)))
+  if (maybe_ne (GET_MODE_NUNITS (value_mode), GET_MODE_NUNITS (cmp_op_mode)))
     return false;
 
   if (TREE_CODE_CLASS (code) != tcc_comparison)