The strength-reduction implementation in expmed.c will assess the profitability of using shift-and-add using a RTL expression that wraps a MULT (with a power-of-2) in a PLUS. Unless the RISC-V rtx_costs function recognizes this as expressing a sh[123]add instruction, we will return an inflated cost, thus defeating the optimization.
This change adds the necessary idiom recognition to provide an accurate cost for this for of expressing sh[123]add. Instead on expanding to li a5,200 mulw a0,a5,a0 with this change, the expression 'a * 200' is sythesized as: sh2add a0,a0,a0 // *5 = a + 4 * a sh2add a0,a0,a0 // *5 = a + 4 * a slli a0,a0,3 // *8 gcc/ChangeLog: * config/riscv/riscv.c (riscv_rtx_costs): Recognize shNadd, if expressed as a plus and multiplication with a power-of-2. Signed-off-by: Philipp Tomsich <philipp.toms...@vrull.eu> --- gcc/config/riscv/riscv.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c index 8480cf09294..dff4e370471 100644 --- a/gcc/config/riscv/riscv.c +++ b/gcc/config/riscv/riscv.c @@ -2020,6 +2020,20 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN *total = COSTS_N_INSNS (1); return true; } + /* Before strength-reduction, the shNadd can be expressed as the addition + of a multiplication with a power-of-two. If this case is not handled, + the strength-reduction in expmed.c will calculate an inflated cost. */ + if (TARGET_ZBA + && ((!TARGET_64BIT && (mode == SImode)) || + (TARGET_64BIT && (mode == DImode))) + && (GET_CODE (XEXP (x, 0)) == MULT) + && REG_P (XEXP (XEXP (x, 0), 0)) + && CONST_INT_P (XEXP (XEXP (x, 0), 1)) + && IN_RANGE (pow2p_hwi (INTVAL (XEXP (XEXP (x, 0), 1))), 1, 3)) + { + *total = COSTS_N_INSNS (1); + return true; + } /* shNadd.uw pattern for zba. [(set (match_operand:DI 0 "register_operand" "=r") (plus:DI -- 2.32.0