https://gcc.gnu.org/g:76c7c5dc5d13e6e1ccb0fdfed90ebfce308e9279
commit r16-5401-g76c7c5dc5d13e6e1ccb0fdfed90ebfce308e9279 Author: Edwin Lu <[email protected]> Date: Fri Nov 7 10:49:33 2025 -0800 RISC-V: Add flag to adjust mem inlining threshold Add param flags to adjust the memcpy/memove/memset inlining threshold. The threshold can be updated with --param=<routine>-size-threshold= Default is currently set for disabled. gcc/ChangeLog: * config/riscv/riscv-string.cc (riscv_expand_block_move_scalar): Add length check. (expand_block_move): Ditto. (expand_vec_setmem): Ditto. * config/riscv/riscv.opt: Add param flags. Signed-off-by: Edwin Lu <[email protected]> Diff: --- gcc/config/riscv/riscv-string.cc | 29 +++++++++++++++++++++++++++++ gcc/config/riscv/riscv.opt | 12 ++++++++++++ 2 files changed, 41 insertions(+) diff --git a/gcc/config/riscv/riscv-string.cc b/gcc/config/riscv/riscv-string.cc index 61c4a095ab4b..2d662b4ce495 100644 --- a/gcc/config/riscv/riscv-string.cc +++ b/gcc/config/riscv/riscv-string.cc @@ -923,6 +923,10 @@ riscv_expand_block_move_scalar (rtx dest, rtx src, rtx length) unsigned HOST_WIDE_INT hwi_length = UINTVAL (length); unsigned HOST_WIDE_INT factor, align; + if (riscv_memcpy_size_threshold >= 0 + && hwi_length > riscv_memcpy_size_threshold) + return false; + if (riscv_slow_unaligned_access_p) { align = MIN (MIN (MEM_ALIGN (src), MEM_ALIGN (dest)), BITS_PER_WORD); @@ -1233,6 +1237,21 @@ expand_block_move (rtx dst_in, rtx src_in, rtx length_in, bool movmem_p) if (!use_vector_stringop_p (info, potential_ew, length_in)) return false; + if (CONST_INT_P (length_in)) + { + HOST_WIDE_INT length = INTVAL (length_in); + if (movmem_p + && riscv_memmove_size_threshold >= 0 + && length > riscv_memmove_size_threshold) + return false; + else if (!movmem_p + && riscv_memmove_size_threshold >= 0 + && length > riscv_memcpy_size_threshold) + return false; + } + else + return false; + /* Inlining general memmove is a pessimisation: we can't avoid having to decide which direction to go at runtime, which is costly in instruction count however for situations where the entire move fits in one vector @@ -1615,6 +1634,16 @@ expand_vec_setmem (rtx dst_in, rtx length_in, rtx fill_value_in) if (!use_vector_stringop_p (info, 1, length_in) || info.need_loop) return false; + if (CONST_INT_P (length_in)) + { + HOST_WIDE_INT length = INTVAL (length_in); + if (riscv_memset_size_threshold >= 0 + && length > riscv_memset_size_threshold) + return false; + } + else + return false; + rtx dst_addr = copy_addr_to_reg (XEXP (dst_in, 0)); rtx dst = change_address (dst_in, info.vmode, dst_addr); diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt index 6543fd1c4a72..b334e6c10c8f 100644 --- a/gcc/config/riscv/riscv.opt +++ b/gcc/config/riscv/riscv.opt @@ -361,6 +361,18 @@ mstringop-strategy= Target RejectNegative Joined Enum(stringop_strategy) Var(stringop_strategy) Init(STRATEGY_AUTO) Specify stringop expansion strategy. +-param=memcpy-size-threshold= +Target Joined UInteger Var(riscv_memcpy_size_threshold) Init(-1) Param +Constant memcpy size in bytes above which to start using libcalls over inlining. + +-param=memmove-size-threshold= +Target Joined UInteger Var(riscv_memmove_size_threshold) Init(-1) Param +Constant memmove size in bytes above which to start using libcalls over inlining. + +-param=memset-size-threshold= +Target Joined UInteger Var(riscv_memset_size_threshold) Init(-1) Param +Constant memset size in bytes above which to start using libcalls over inlining. + Enum Name(rvv_vector_bits) Type(enum rvv_vector_bits_enum) The possible RVV vector register lengths:
