https://gcc.gnu.org/g:cc2b8e4c2289e7d7feffc060f84c13bc21e27d0f
commit r17-5762-gcc2b8e4c2289e7d7feffc060f84c13bc21e27d0f Author: Robin Dapp <[email protected]> Date: Mon Oct 19 12:04:40 2026 +0200 optab: Make SAD a convert optab. This patch makes the "sum of absolute differences" a convert optab and adjusts the docs. gcc/ChangeLog: * config/aarch64/aarch64-simd.md (<su>sadv8qi): Rename... (<su>sadv2siv8qi): ...To this. (<su>sadv16qi): Likewise. (<su>sadv4siv16qi): Likewise. * config/aarch64/aarch64-sve.md (<su>sad<vsi2qi>): Likewise. (<su>sad<mode><vsi2qi>): Likewise. * config/arm/neon.md (<sup>sadv16qi): Likewise. (<sup>sadv4siv16qi): Likewise. * config/i386/i386.cc (ix86_vector_costs::add_stmt_cost): Change name in comment. * config/i386/mmx.md (usadv8qi): Rename... (usadv2siv8qi): ...To this. * config/i386/sse.md (usadv16qi): Likewise. (usadv4siv16qi): Likewise. (usadv32qi): Likewise. (usadv8siv32qi): Likewise. (usadv64qi): Likewise. (usadv16siv64qi): Likewise. * config/loongarch/lasx.md (usadv32qi): Likewise. (usadv8siv32qi): Likewise. (ssadv32qi): Likewise. (ssadv8siv32qi): Likewise. * config/loongarch/lsx.md (usadv16qi): Likewise. (usadv4siv16qi): Likewise. (ssadv16qi): Likewise. (ssadv4siv16qi): Likewise. * config/rs6000/altivec.md (usadv16qi): Likewise. (usadv4siv16qi): Likewise. (usadv8hi): Likewise. (usadv4siv8hi): Likewise. * doc/md.texi: Adjust docs. * optabs.cc (expand_widen_pattern_expr): Add SAD_EXPR. * optabs.def (OPTAB_CD): Ditto. (OPTAB_D): Remove. * tree-vect-patterns.cc (vect_recog_sad_pattern): Use conv_optab. Diff: --- gcc/config/aarch64/aarch64-simd.md | 4 ++-- gcc/config/aarch64/aarch64-sve.md | 2 +- gcc/config/arm/neon.md | 2 +- gcc/config/i386/i386.cc | 2 +- gcc/config/i386/mmx.md | 2 +- gcc/config/i386/sse.md | 6 +++--- gcc/config/loongarch/lasx.md | 4 ++-- gcc/config/loongarch/lsx.md | 4 ++-- gcc/config/rs6000/altivec.md | 4 ++-- gcc/doc/md.texi | 11 ++++++----- gcc/optabs.cc | 3 ++- gcc/optabs.def | 4 ++-- gcc/tree-vect-patterns.cc | 4 ++-- 13 files changed, 27 insertions(+), 25 deletions(-) diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 6b4aff5e21e2..53c2cbf0f687 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -1235,7 +1235,7 @@ [(set_attr "type" "neon_reduc_add<q>")] ) -(define_expand "<su>sadv8qi" +(define_expand "<su>sadv2siv8qi" [(use (match_operand:V2SI 0 "register_operand")) (USMAX:V8QI (match_operand:V8QI 1 "register_operand") (match_operand:V8QI 2 "register_operand")) @@ -1270,7 +1270,7 @@ ;; but for TARGET_DOTPROD still emits a UDOT as the absolute difference is ;; unsigned. -(define_expand "<su>sadv16qi" +(define_expand "<su>sadv4siv16qi" [(use (match_operand:V4SI 0 "register_operand")) (USMAX:V16QI (match_operand:V16QI 1 "register_operand") (match_operand:V16QI 2 "register_operand")) diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md index da5e5ce49f26..de17b5f63874 100644 --- a/gcc/config/aarch64/aarch64-sve.md +++ b/gcc/config/aarch64/aarch64-sve.md @@ -7924,7 +7924,7 @@ ;; [SU]ABD diff.b, p0/m, op1.b, op2.b ;; MOVPRFX op0, op3 // If necessary ;; UDOT op0.s, diff.b, ones.b -(define_expand "<su>sad<vsi2qi>" +(define_expand "<su>sad<mode><vsi2qi>" [(use (match_operand:SVE_FULL_SDI 0 "register_operand")) (USMAX:<VSI2QI> (match_operand:<VSI2QI> 1 "register_operand") (match_operand:<VSI2QI> 2 "register_operand")) diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index 3c908db4538a..d8f5c56ea6bd 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -2654,7 +2654,7 @@ [(set_attr "type" "neon_arith_acc<q>")] ) -(define_expand "<sup>sadv16qi" +(define_expand "<sup>sadv4siv16qi" [(use (match_operand:V4SI 0 "register_operand")) (unspec:V16QI [(use (match_operand:V16QI 1 "register_operand")) (use (match_operand:V16QI 2 "register_operand"))] VABAL) diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index b13b07fac232..25d7e813446c 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -27359,7 +27359,7 @@ ix86_vector_costs::add_stmt_cost (int count, vect_cost_for_stmt kind, /* Vectorizer lane_reducing_op_p supports DOT_PROX_EXPR, WIDEN_SUM_EXPR and SAD_EXPR, x86 backend only supports - SAD_EXPR (usad{v16qi,v32qi,v64qi}) and DOT_PROD_EXPR. */ + SAD_EXPR (usad{v4siv16qi,v8siv32qi,v16siv64qi}) and DOT_PROD_EXPR. */ case DOT_PROD_EXPR: rhs1 = gimple_assign_rhs1 (stmt_info->stmt); mode_rhs = TYPE_MODE (TREE_TYPE (rhs1)); diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md index fa51f6a79918..96e173efaa58 100644 --- a/gcc/config/i386/mmx.md +++ b/gcc/config/i386/mmx.md @@ -6684,7 +6684,7 @@ DONE; }) -(define_expand "usadv8qi" +(define_expand "usadv2siv8qi" [(match_operand:V2SI 0 "register_operand") (match_operand:V8QI 1 "register_operand") (match_operand:V8QI 2 "register_operand") diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 37a15fabba98..4e6761a71f62 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -18133,7 +18133,7 @@ ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands); }) -(define_expand "usadv16qi" +(define_expand "usadv4siv16qi" [(match_operand:V4SI 0 "register_operand") (match_operand:V16QI 1 "register_operand") (match_operand:V16QI 2 "vector_operand") @@ -18148,7 +18148,7 @@ DONE; }) -(define_expand "usadv32qi" +(define_expand "usadv8siv32qi" [(match_operand:V8SI 0 "register_operand") (match_operand:V32QI 1 "register_operand") (match_operand:V32QI 2 "nonimmediate_operand") @@ -18163,7 +18163,7 @@ DONE; }) -(define_expand "usadv64qi" +(define_expand "usadv16siv64qi" [(match_operand:V16SI 0 "register_operand") (match_operand:V64QI 1 "register_operand") (match_operand:V64QI 2 "nonimmediate_operand") diff --git a/gcc/config/loongarch/lasx.md b/gcc/config/loongarch/lasx.md index 71bbaaa475c9..23ba70c97dc0 100644 --- a/gcc/config/loongarch/lasx.md +++ b/gcc/config/loongarch/lasx.md @@ -3746,7 +3746,7 @@ gen_lasx_xvmulwod_<dlasxfmt>_<lasxfmt><u>; DONE; }) -(define_expand "usadv32qi" +(define_expand "usadv8siv32qi" [(match_operand:V8SI 0 "register_operand") (match_operand:V32QI 1 "register_operand") (match_operand:V32QI 2 "register_operand") @@ -3763,7 +3763,7 @@ gen_lasx_xvmulwod_<dlasxfmt>_<lasxfmt><u>; DONE; }) -(define_expand "ssadv32qi" +(define_expand "ssadv8siv32qi" [(match_operand:V8SI 0 "register_operand") (match_operand:V32QI 1 "register_operand") (match_operand:V32QI 2 "register_operand") diff --git a/gcc/config/loongarch/lsx.md b/gcc/config/loongarch/lsx.md index 0d561cc665e7..051ce18bd7e1 100644 --- a/gcc/config/loongarch/lsx.md +++ b/gcc/config/loongarch/lsx.md @@ -2844,7 +2844,7 @@ DONE; }) -(define_expand "usadv16qi" +(define_expand "usadv4siv16qi" [(match_operand:V4SI 0 "register_operand") (match_operand:V16QI 1 "register_operand") (match_operand:V16QI 2 "register_operand") @@ -2861,7 +2861,7 @@ DONE; }) -(define_expand "ssadv16qi" +(define_expand "ssadv4siv16qi" [(match_operand:V4SI 0 "register_operand") (match_operand:V16QI 1 "register_operand") (match_operand:V16QI 2 "register_operand") diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md index ded762720e18..9ca49a32801f 100644 --- a/gcc/config/rs6000/altivec.md +++ b/gcc/config/rs6000/altivec.md @@ -4581,7 +4581,7 @@ ;; Due to saturating semantics, we can't combine the sum-across ;; with the vector accumulate in vsum4ubs. A vadduwm is needed. -(define_expand "usadv16qi" +(define_expand "usadv4siv16qi" [(use (match_operand:V4SI 0 "register_operand")) (use (match_operand:V16QI 1 "register_operand")) (use (match_operand:V16QI 2 "register_operand")) @@ -4602,7 +4602,7 @@ ;; Since vsum4shs is saturating and further performs signed ;; arithmetic, we can't combine the sum-across with the vector ;; accumulate in vsum4shs. A vadduwm is needed. -(define_expand "usadv8hi" +(define_expand "usadv4siv8hi" [(use (match_operand:V4SI 0 "register_operand")) (use (match_operand:V8HI 1 "register_operand")) (use (match_operand:V8HI 2 "register_operand")) diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index e25e5fdb49a7..a22365db6aaf 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -5086,16 +5086,17 @@ raised and a quiet @code{NaN} is returned. All operands have mode @var{m}, which is a scalar or vector floating-point mode. These patterns are not allowed to @code{FAIL}. -@mdindex ssad@var{m} -@mdindex usad@var{m} -@item @samp{ssad@var{m}} -@item @samp{usad@var{m}} +@mdindex ssad@var{m}@var{n} +@mdindex usad@var{m}@var{n} +@item @samp{ssad@var{m}@var{n}} +@itemx @samp{usad@var{m}@var{n}} Compute the sum of absolute differences of two signed/unsigned elements. Operand 1 and operand 2 are of the same mode. Their absolute difference, which is of a wider mode, is computed and added to operand 3. Operand 3 is of a mode equal or wider than the mode of the absolute difference. The result is placed in operand 0, which is of the same mode as operand 3. -@var{m} is the mode of operand 1 and operand 2. +@var{m} is the mode of operand 0 and @var{n} the mode of operand 1 and +operand 2. @mdindex reduc_widen_ssum@var{n}@var{m}3 @mdindex reduc_widen_usum@var{n}@var{m}3 diff --git a/gcc/optabs.cc b/gcc/optabs.cc index 3b7cf55a81bd..524a6836495b 100644 --- a/gcc/optabs.cc +++ b/gcc/optabs.cc @@ -320,7 +320,8 @@ expand_widen_pattern_expr (const_sepops ops, rtx op0, rtx op1, rtx wide_op, = optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), optab_default); if (ops->code == WIDEN_MULT_PLUS_EXPR || ops->code == WIDEN_MULT_MINUS_EXPR - || ops->code == DOT_PROD_EXPR) + || ops->code == DOT_PROD_EXPR + || ops->code == SAD_EXPR) icode = find_widening_optab_handler (widen_pattern_optab, TYPE_MODE (TREE_TYPE (ops->op2)), tmode0); diff --git a/gcc/optabs.def b/gcc/optabs.def index 4ee434ea1a7c..8a5b37558b10 100644 --- a/gcc/optabs.def +++ b/gcc/optabs.def @@ -114,6 +114,8 @@ OPTAB_CD(vec_init_optab, "vec_init$a$b") OPTAB_CD (sdot_prod_optab, "sdot_prod$I$a$b") OPTAB_CD (udot_prod_optab, "udot_prod$I$a$b") OPTAB_CD (usdot_prod_optab, "usdot_prod$I$a$b") +OPTAB_CD (usad_optab, "usad$I$a$b") +OPTAB_CD (ssad_optab, "ssad$I$a$b") OPTAB_CD (while_ult_optab, "while_ult$a$b") OPTAB_CD (select_vl_optab, "select_vl$a$b") @@ -439,8 +441,6 @@ OPTAB_D (savg_floor_optab, "avg$a3_floor") OPTAB_D (uavg_floor_optab, "uavg$a3_floor") OPTAB_D (savg_ceil_optab, "avg$a3_ceil") OPTAB_D (uavg_ceil_optab, "uavg$a3_ceil") -OPTAB_D (usad_optab, "usad$I$a") -OPTAB_D (ssad_optab, "ssad$I$a") OPTAB_D (smulhs_optab, "smulhs$a3") OPTAB_D (smulhrs_optab, "smulhrs$a3") OPTAB_D (umulhs_optab, "umulhs$a3") diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc index 79e984af0244..d79f625280a6 100644 --- a/gcc/tree-vect-patterns.cc +++ b/gcc/tree-vect-patterns.cc @@ -1506,8 +1506,8 @@ vect_recog_sad_pattern (vec_info *vinfo, vect_pattern_detected ("vect_recog_sad_pattern", last_stmt); tree half_vectype; - if (!vect_supportable_direct_optab_p (vinfo, sum_type, SAD_EXPR, half_type, - type_out, &half_vectype)) + if (!vect_supportable_conv_optab_p (vinfo, sum_type, SAD_EXPR, half_type, + type_out, &half_vectype)) return NULL; /* Get the inputs to the SAD_EXPR in the appropriate types. */
