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] }
