Oluwatamilore Adebayo <oluwatamilore.adeb...@arm.com> writes: > From: oluade01 <oluwatamilore.adeb...@arm.com> > > This updates vect_recog_abd_pattern to recognize the widening > variant of absolute difference (ABDL, ABDL2). > > gcc/ChangeLog: > > * internal-fn.cc (widening_fn_p, decomposes_to_hilo_fn_p): > Add IFN_VEC_WIDEN_ABD to the switch statement. > * internal-fn.def (VEC_WIDEN_ABD): New internal hilo optab. > * optabs.def (vec_widen_sabd_optab, > vec_widen_sabd_hi_optab, vec_widen_sabd_lo_optab, > vec_widen_sabd_odd_even, vec_widen_sabd_even_optab, > vec_widen_uabd_optab, > vec_widen_uabd_hi_optab, vec_widen_uabd_lo_optab, > vec_widen_uabd_odd_even, vec_widen_uabd_even_optab): > New optabs. > * tree-vect-patterns.cc (vect_recog_abd_pattern): Update to > to build a VEC_WIDEN_ABD call if the input precision is smaller > than the precision of the output. > (vect_recog_widen_abd_pattern): Should an ABD expression be > found preceeding an extension, replace the two with a > VEC_WIDEN_ABD.
Thanks. Testing on an updated trunk shows that we need to check INTEGRAL_TYPE_P… > @@ -1703,6 +1736,66 @@ vect_recog_widen_minus_pattern (vec_info *vinfo, > stmt_vec_info last_stmt_info, > &subtype); > } > > +/* Try to detect abd on widened inputs, converting IFN_ABD > + to IFN_VEC_WIDEN_ABD. */ > +static gimple * > +vect_recog_widen_abd_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo, > + tree *type_out) > +{ > + gassign *last_stmt = dyn_cast <gassign *> (STMT_VINFO_STMT (stmt_vinfo)); > + if (!last_stmt || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code > (last_stmt))) > + return NULL; > + > + tree last_rhs = gimple_assign_rhs1 (last_stmt); > + > + tree in_type = TREE_TYPE (last_rhs); > + tree out_type = TREE_TYPE (gimple_assign_lhs (last_stmt)); > + if (TYPE_PRECISION (in_type) * 2 != TYPE_PRECISION (out_type) > + || !TYPE_UNSIGNED (in_type)) > + return NULL; …here to avoid new stricter testing for TYPE_PRECISION on VECTOR_TYPEs. I've pushed the series with that change. Thanks again for working on this. It's a really nice improvement. Richard > + > + vect_unpromoted_value unprom; > + tree op = vect_look_through_possible_promotion (vinfo, last_rhs, &unprom); > + if (!op || TYPE_PRECISION (TREE_TYPE (op)) != TYPE_PRECISION (in_type)) > + return NULL; > + > + stmt_vec_info abd_pattern_vinfo = vect_get_internal_def (vinfo, op); > + if (!abd_pattern_vinfo) > + return NULL; > + > + abd_pattern_vinfo = vect_stmt_to_vectorize (abd_pattern_vinfo); > + gcall *abd_stmt = dyn_cast <gcall *> (STMT_VINFO_STMT (abd_pattern_vinfo)); > + if (!abd_stmt > + || !gimple_call_internal_p (abd_stmt) > + || gimple_call_internal_fn (abd_stmt) != IFN_ABD) > + return NULL; > + > + tree vectype_in = get_vectype_for_scalar_type (vinfo, in_type); > + tree vectype_out = get_vectype_for_scalar_type (vinfo, out_type); > + > + code_helper dummy_code; > + int dummy_int; > + auto_vec<tree> dummy_vec; > + if (!supportable_widening_operation (vinfo, IFN_VEC_WIDEN_ABD, stmt_vinfo, > + vectype_out, vectype_in, > + &dummy_code, &dummy_code, > + &dummy_int, &dummy_vec)) > + return NULL; > + > + vect_pattern_detected ("vect_recog_widen_abd_pattern", last_stmt); > + > + *type_out = vectype_out; > + > + tree abd_oprnd0 = gimple_call_arg (abd_stmt, 0); > + tree abd_oprnd1 = gimple_call_arg (abd_stmt, 1); > + tree widen_abd_result = vect_recog_temp_ssa_var (out_type, NULL); > + gcall *widen_abd_stmt = gimple_build_call_internal (IFN_VEC_WIDEN_ABD, 2, > + abd_oprnd0, abd_oprnd1); > + gimple_call_set_lhs (widen_abd_stmt, widen_abd_result); > + gimple_set_location (widen_abd_stmt, gimple_location (last_stmt)); > + return widen_abd_stmt; > +} > + > /* Function vect_recog_ctz_ffs_pattern > > Try to find the following pattern: > @@ -6670,6 +6763,7 @@ static vect_recog_func vect_vect_recog_func_ptrs[] = { > { vect_recog_mask_conversion_pattern, "mask_conversion" }, > { vect_recog_widen_plus_pattern, "widen_plus" }, > { vect_recog_widen_minus_pattern, "widen_minus" }, > + { vect_recog_widen_abd_pattern, "widen_abd" }, > /* These must come after the double widening ones. */ > };