Jennifer Schmitz <jschm...@nvidia.com> writes: > @@ -3672,6 +3673,48 @@ gimple_folder::fold_pfalse () > return nullptr; > } > > +/* Convert the lhs and all non-boolean vector-type operands to TYPE. > + Pass the converted variables to the callback FP, and finally convert the > + result back to the original type. Add the necessary conversion statements. > + Return the new call. */ > +gimple * > +gimple_folder::convert_and_fold (tree type, > + gimple *(*fp) (gimple_folder &, > + tree, vec<tree> &)) > +{ > + gcc_assert (VECTOR_TYPE_P (type) > + && TYPE_MODE (type) != VNx16BImode); > + tree old_ty = TREE_TYPE (lhs); > + gimple_seq stmts = NULL; > + tree lhs_conv, op, op_ty, t; > + gimple *g, *new_stmt;
Sorry for the last-minute minor request, but: it would be nice to declare these at the point of initialisation, for consistency with the rest of the function. > + bool convert_lhs_p = !useless_type_conversion_p (type, old_ty); > + lhs_conv = convert_lhs_p ? create_tmp_var (type) : lhs; > + unsigned int num_args = gimple_call_num_args (call); > + auto_vec<tree, 16> args_conv; > + args_conv.safe_grow (num_args); > + for (unsigned int i = 0; i < num_args; ++i) > + { > + op = gimple_call_arg (call, i); > + op_ty = TREE_TYPE (op); > + args_conv[i] = > + (VECTOR_TYPE_P (op_ty) > + && TYPE_MODE (op_ty) != VNx16BImode > + && !useless_type_conversion_p (op_ty, type)) > + ? gimple_build (&stmts, VIEW_CONVERT_EXPR, type, op) : op; > + } > + > + new_stmt = fp (*this, lhs_conv, args_conv); > + gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); > + if (convert_lhs_p) > + { > + t = build1 (VIEW_CONVERT_EXPR, old_ty, lhs_conv); > + g = gimple_build_assign (lhs, VIEW_CONVERT_EXPR, t); > + gsi_insert_after (gsi, g, GSI_SAME_STMT); > + } > + return new_stmt; > +} > + > /* Fold the call to constant VAL. */ > gimple * > gimple_folder::fold_to_cstu (poly_uint64 val) > diff --git a/gcc/config/aarch64/aarch64-sve-builtins.h > b/gcc/config/aarch64/aarch64-sve-builtins.h > index 6f22868f9b3..02ae098ed32 100644 > --- a/gcc/config/aarch64/aarch64-sve-builtins.h > +++ b/gcc/config/aarch64/aarch64-sve-builtins.h > @@ -421,6 +421,7 @@ public: > tree scalar_type (unsigned int) const; > tree vector_type (unsigned int) const; > tree tuple_type (unsigned int) const; > + tree signed_type (unsigned int) const; > unsigned int elements_per_vq (unsigned int) const; > machine_mode vector_mode (unsigned int) const; > machine_mode tuple_mode (unsigned int) const; > @@ -649,6 +650,8 @@ public: > gcall *redirect_call (const function_instance &); > gimple *redirect_pred_x (); > gimple *fold_pfalse (); > + gimple *convert_and_fold (tree, gimple *(*) (gimple_folder &, > + tree, vec<tree> &)); > > gimple *fold_to_cstu (poly_uint64); > gimple *fold_to_pfalse (); > @@ -884,6 +887,20 @@ find_type_suffix (type_class_index tclass, unsigned int > element_bits) > gcc_unreachable (); > } > > +/* Return the type suffix of the signed type of width ELEMENT_BITS. */ > +inline type_suffix_index > +signed_type_suffix_index (unsigned int element_bits) > +{ > + switch (element_bits) > + { > + case 8: return TYPE_SUFFIX_s8; > + case 16: return TYPE_SUFFIX_s16; > + case 32: return TYPE_SUFFIX_s32; > + case 64: return TYPE_SUFFIX_s64; > + } > + gcc_unreachable (); > +} > + We could drop this and instead replace calls with: find_type_suffix (TYPE_signed, element_bits) > /* Return the single field in tuple type TYPE. */ > inline tree > tuple_type_field (tree type) > @@ -1049,6 +1066,20 @@ function_instance::tuple_type (unsigned int i) const > return acle_vector_types[num_vectors - 1][type_suffix (i).vector_type]; > } > > +/* Return the signed vector type of width ELEMENT_BITS. */ > +inline tree > +function_instance::signed_type (unsigned int element_bits) const > +{ > + switch (element_bits) > + { > + case 8: return acle_vector_types[0][VECTOR_TYPE_svint8_t]; > + case 16: return acle_vector_types[0][VECTOR_TYPE_svint16_t]; > + case 32: return acle_vector_types[0][VECTOR_TYPE_svint32_t]; > + case 64: return acle_vector_types[0][VECTOR_TYPE_svint64_t]; > + } > + gcc_unreachable (); > +} > + And for this, I think we should instead make: /* Return the vector type associated with TYPE. */ static tree get_vector_type (sve_type type) { auto vector_type = type_suffixes[type.type].vector_type; return acle_vector_types[type.num_vectors - 1][vector_type]; } public, or perhaps just define it inline in aarch64-sve-builtins.h. OK with those changes, thanks. Richard