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.  */

Reply via email to