https://gcc.gnu.org/g:cf3eaa0ee525be8ad51bb4cb2e3eea94e9944932

commit r17-5763-gcf3eaa0ee525be8ad51bb4cb2e3eea94e9944932
Author: Robin Dapp <[email protected]>
Date:   Wed Sep 2 16:00:27 2026 +0200

    RISC-V: Add usad patterns.
    
    This patch adds the native usad qi->hi and hi->si variants as well as
    the qi->si synthesized variant to autovec.md.  The latter uses
    vmv.v.i, vwabdau, and vwadd.  An in-flight vectorizer patch is expected
    to narrow the accumulator for e.g. x264 loops so we can use the native
    variants directly rather than the synthesized one.
    
    gcc/ChangeLog:
    
            * config/riscv/autovec.md (<su>abd<mode>3): Adjust comment.
            (<su>sad<mode><v_double_trunc>): New expander.
            (<su>sad<mode><v_quad_trunc>): Likewise.
            * config/riscv/vector-iterators.md: Split VWEXTI_HS into
            VWEXTI_H and VWEXTI_S.
    
    gcc/testsuite/ChangeLog:
    
            * lib/target-supports.exp: Add target selectors.

Diff:
---
 gcc/config/riscv/autovec.md           | 88 ++++++++++++++++++++++++++---------
 gcc/config/riscv/vector-iterators.md  | 10 ++--
 gcc/testsuite/lib/target-supports.exp | 36 ++++++++++++++
 3 files changed, 109 insertions(+), 25 deletions(-)

diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index f6157b8d4d53..6084027ce6f5 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -1135,9 +1135,9 @@
 }
 [(set_attr "type" "vialu")])
 
-;; 
-------------------------------------------------------------------------------
+;; ----------------------------------------------------------------------------
 ;; - [INT] ABS expansion
-;; 
-------------------------------------------------------------------------------
+;; ----------------------------------------------------------------------------
 
 (define_expand "abs<mode>2"
   [(set (match_operand:V_VLSI 0 "register_operand")
@@ -1163,6 +1163,70 @@
   DONE;
 })
 
+;; ----------------------------------------------------------------------------
+;; - [INT] Absolute differences
+;; ----------------------------------------------------------------------------
+(define_insn_and_split "<su>abd<mode>3"
+  [(set (match_operand:VI_QH 0 "register_operand" "=vr")
+       (unspec:VI_QH
+        [(match_operand:VI_QH 1 "register_operand" "vr")
+         (match_operand:VI_QH 2 "register_operand" "vr")]
+        UNSPEC_VABD))]
+  "TARGET_ZVABD && can_create_pseudo_p ()"
+  "#"
+  "&& 1"
+  [(const_int 0)]
+{
+  riscv_vector::emit_vlmax_insn (CODE_FOR_pred_vabd<su><mode>,
+                                riscv_vector::BINARY_OP, operands);
+  DONE;
+}
+[(set_attr "type" "vialu")])
+
+;; ----------------------------------------------------------------------------
+;; - [INT] Sum of absolute differences
+;; ----------------------------------------------------------------------------
+
+;; These are supported directly.
+(define_expand "<su>sad<mode><v_double_trunc>"
+  [(set (match_operand:VWEXTI_HS 0 "register_operand" "=vr")
+    (unspec:VWEXTI_HS
+        [(match_operand:<V_DOUBLE_TRUNC> 1 "register_operand" "vr")
+         (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand" "vr")
+         (match_operand:VWEXTI_HS 3 "register_operand")]
+        UNSPEC_VABD))]
+  "TARGET_ZVABD"
+{
+  rtx ops[] = {operands[0], operands[3], operands[1], operands[2]};
+  riscv_vector::emit_vlmax_insn (CODE_FOR_pred_widen_abd_plus<su><mode>,
+                                riscv_vector::WIDEN_TERNARY_OP, ops);
+  DONE;
+})
+
+;; These we can synthesize.
+(define_expand "<su>sad<mode><v_quad_trunc>"
+  [(set (match_operand:VWEXTI_S 0 "register_operand" "=vr")
+    (unspec:VWEXTI_S
+        [(match_operand:<V_QUAD_TRUNC> 1 "register_operand" "vr")
+         (match_operand:<V_QUAD_TRUNC> 2 "register_operand" "vr")
+         (match_operand:VWEXTI_S 3 "register_operand")]
+        UNSPEC_VABD))]
+  "TARGET_ZVABD"
+{
+  rtx abd = gen_reg_rtx (<V_DOUBLE_TRUNC>mode);
+  emit_move_insn (abd, CONST0_RTX (<V_DOUBLE_TRUNC>mode));
+  rtx ops1[] = {abd, abd, operands[1], operands[2]};
+  insn_code icode = CODE_FOR_pred_widen_abd_plus<su><v_double_trunc>;
+  riscv_vector::emit_vlmax_insn (icode, riscv_vector::WIDEN_TERNARY_OP, ops1);
+
+  rtx ops2[] = {operands[0], operands[3], abd};
+  riscv_vector::emit_vlmax_insn (code_for_pred_single_widen_add (ZERO_EXTEND,
+                                                                <MODE>mode),
+                                riscv_vector::BINARY_OP, ops2);
+
+  DONE;
+})
+
 ;; 
-------------------------------------------------------------------------------
 ;; ---- [FP] Unary operations
 ;; 
-------------------------------------------------------------------------------
@@ -3091,23 +3155,3 @@
     riscv_vector::expand_strided_store (<MODE>mode, operands);
     DONE;
   })
-
-; ========
-; == Absolute difference (not including sum)
-; ========
-(define_insn_and_split "<su>abd<mode>3"
-  [(set (match_operand:VI_QH 0 "register_operand" "=vr")
-       (unspec:VI_QH
-        [(match_operand:VI_QH 1 "register_operand" "vr")
-         (match_operand:VI_QH 2 "register_operand" "vr")]
-        UNSPEC_VABD))]
-  "TARGET_ZVABD && can_create_pseudo_p ()"
-  "#"
-  "&& 1"
-  [(const_int 0)]
-{
-  riscv_vector::emit_vlmax_insn (CODE_FOR_pred_vabd<su><mode>,
-                                riscv_vector::BINARY_OP, operands);
-  DONE;
-}
-[(set_attr "type" "vialu")])
diff --git a/gcc/config/riscv/vector-iterators.md 
b/gcc/config/riscv/vector-iterators.md
index c0475b6b72af..275cbdcc18ff 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -1258,11 +1258,9 @@
   (RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_VECTOR_ELEN_64")
 ])
 
-(define_mode_iterator VWEXTI_HS [
+(define_mode_iterator VWEXTI_H [
   RVVM8HI RVVM4HI RVVM2HI RVVM1HI RVVMF2HI (RVVMF4HI "TARGET_VECTOR_ELEN_64")
 
-  RVVM8SI RVVM4SI RVVM2SI RVVM1SI (RVVMF2SI "TARGET_VECTOR_ELEN_64")
-
   (V1HI "riscv_vector::vls_mode_valid_p (V1HImode)")
   (V2HI "riscv_vector::vls_mode_valid_p (V2HImode)")
   (V4HI "riscv_vector::vls_mode_valid_p (V4HImode)")
@@ -1275,6 +1273,10 @@
   (V512HI "riscv_vector::vls_mode_valid_p (V512HImode) && TARGET_MIN_VLEN >= 
1024")
   (V1024HI "riscv_vector::vls_mode_valid_p (V1024HImode) && TARGET_MIN_VLEN >= 
2048")
   (V2048HI "riscv_vector::vls_mode_valid_p (V2048HImode) && TARGET_MIN_VLEN >= 
4096")
+])
+
+(define_mode_iterator VWEXTI_S [
+  RVVM8SI RVVM4SI RVVM2SI RVVM1SI (RVVMF2SI "TARGET_VECTOR_ELEN_64")
   (V1SI "riscv_vector::vls_mode_valid_p (V1SImode)")
   (V2SI "riscv_vector::vls_mode_valid_p (V2SImode)")
   (V4SI "riscv_vector::vls_mode_valid_p (V4SImode)")
@@ -1288,6 +1290,8 @@
   (V1024SI "riscv_vector::vls_mode_valid_p (V1024SImode) && TARGET_MIN_VLEN >= 
4096")
 ])
 
+(define_mode_iterator VWEXTI_HS [VWEXTI_H VWEXTI_S])
+
 (define_mode_iterator VWEXTI_D [
   (RVVM8DI "TARGET_VECTOR_ELEN_64") (RVVM4DI "TARGET_VECTOR_ELEN_64")
   (RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64")
diff --git a/gcc/testsuite/lib/target-supports.exp 
b/gcc/testsuite/lib/target-supports.exp
index 2dd33bd1b0c9..74224d35b56b 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -2316,6 +2316,14 @@ proc check_effective_target_riscv_zvbb { } {
     }]
 }
 
+proc check_effective_target_riscv_zvabd { } {
+    return [check_no_compiler_messages riscv_ext_zvabd assembly {
+       #ifndef __riscv_zvabd
+       #error "Not __riscv_zvabd"
+       #endif
+    }]
+}
+
 # Return 1 if the target arch supports the Zbc extension, 0 otherwise.
 # Cache the result.
 
@@ -2591,6 +2599,27 @@ proc check_effective_target_riscv_zvbb_ok { } {
     return 0
 }
 
+proc check_effective_target_riscv_zvabd_ok { } {
+    if { ![istarget riscv*-*-*] } {
+       return 0
+    }
+
+    set gcc_march [riscv_get_arch]
+    if { [check_effective_target_riscv_zvabd] } {
+       set opts ""
+    } else {
+       set opts "-march=${gcc_march}_zvabd"
+    }
+
+    return [check_runtime ${gcc_march}_zvabd_exec {
+       int main()
+       {
+           asm ("vsetivli zero,8,e8,m1,ta,ma");
+           asm ("vwabdau.vv v8,v16,v18" : : : "v8", "v9");
+           return 0;
+       } } $opts]
+}
+
 # Return 1 if we can load a vector from a 1-byte aligned address.
 
 proc check_effective_target_riscv_v_misalign_ok { } {
@@ -2867,6 +2896,13 @@ proc remove_options_for_riscv_zvbb { flags } {
     return [add_options_for_riscv_multi_letter_ext zvbb $flags]
 }
 
+proc add_options_for_riscv_zvabd { flags } {
+    if { ![check_effective_target_riscv_zvabd_ok] } {
+       return $flags
+    }
+    return [add_options_for_riscv_z_ext zvabd $flags]
+}
+
 proc add_options_for_riscv_zvfh { flags } {
     return [add_options_for_riscv_multi_letter_ext zvfh $flags]
 }

Reply via email to