@@ -66,8 +66,8 @@ apply_predication (const function_instance &instance, tree return_type,
the same type as the result. For unary_convert_narrowt it also
provides the "bottom" half of active elements, and is present
for all types of predication. */
- if ((argument_types.length () == 2 && instance.pred == PRED_m)
- || instance.shape == shapes::unary_convert_narrowt)
+ auto nargs = argument_types.length () - 1;
+ if (instance.shape->has_merge_argument_p (instance, nargs))
argument_types.quick_insert (0, return_type);
}
}
@@ -3271,6 +3271,12 @@ SHAPE (unary_convert)
predicate. */
struct unary_convert_narrowt_def : public overloaded_base<1>
{
+ bool
+ has_merge_argument_p (const function_instance &, unsigned int) const override
+ {
+ return true;
+ }
+
void
build (function_builder &b, const function_group_info &group) const override
{
@@ -2287,7 +2287,7 @@ function_resolver::check_gp_argument (unsigned int nops,
if (pred != PRED_none)
{
/* Unary merge operations should use resolve_unary instead. */
- gcc_assert (nops != 1 || pred != PRED_m);
+ gcc_assert (!shape->has_merge_argument_p (*this, nops));
nargs = nops + 1;
if (!check_num_arguments (nargs)
|| !require_vector_type (i, VECTOR_TYPE_svbool_t))
@@ -2997,7 +2997,7 @@ function_expander::get_fallback_value (machine_mode mode, unsigned int nops,
gcc_assert (pred == PRED_m || pred == PRED_x);
if (merge_argno == DEFAULT_MERGE_ARGNO)
- merge_argno = nops == 1 && pred == PRED_m ? 0 : 1;
+ merge_argno = shape->has_merge_argument_p (*this, nops) ? 0 : 1;
if (merge_argno == 0)
return args[argno++];
@@ -712,6 +712,9 @@ public:
class function_shape
{
public:
+ virtual bool has_merge_argument_p (const function_instance &,
+ unsigned int) const;
+
virtual bool explicit_type_suffix_p (unsigned int) const = 0;
/* True if the group suffix is present in overloaded names.
@@ -987,6 +990,16 @@ function_base::vectors_per_tuple (const function_instance &instance) const
return instance.group_suffix ().vectors_per_tuple;
}
+/* Return true if INSTANCE (which has NARGS arguments) has an initial
+ vector argument whose only purpose is to specify the values of
+ inactive lanes. */
+inline bool
+function_shape::has_merge_argument_p (const function_instance &instance,
+ unsigned int nargs) const
+{
+ return nargs == 1 && instance.pred == PRED_m;
+}
+
/* Return the mode of the result of a call. */
inline machine_mode
function_expander::result_mode () const