Hi Jin,
Just some advice:
>+static bool
>+riscv_set_is_add_addi_p (rtx set)
>+{
>+ return (riscv_set_is_add_p (set)
>+ || riscv_set_is_addi_p (set)
>+ || riscv_set_is_addw_p (set)
>+ || riscv_set_is_addiw_p (set)
>+ || riscv_set_is_adduw_p (set));
>+}
Note that if your microarchtecture always matches add & addi encoding, these
should also be considered:
`mv rd, rs` is encoded as `addi rd, rs, 0`
`c.mv rs, rs` as `c.add rd, x0, rs`
`li c` as `addi rd, x0, c`
>+static bool
>+riscv_set_is_logical_type_p (rtx set,
>+ rtx *src0 = NULL,
>+ rtx *src1 = NULL)
>+{
>+ rtx src = SET_SRC (set);
>+ rtx_code code = GET_CODE (src);
>+ rtx dummy0, dummy1;
>+ if (!src0) src0 = &dummy0;
>+ if (!src1) src1 = &dummy1;
I'm not sure this is valid. In any case, probably a batter idea to check
whether src0/1 is `NULL` explicitly.
>+/* Check for RISCV_FUSE_SLLI_SRLI fusion.
>+ Try:
>+ prev (slli) == (set (reg x2) (ashift (x3, N)))
>+ curr (srli) == (set (reg x2) (lshiftrt (x2, M)))
We had trouble getting this to be generated properly with the matching
destination register because of this pattern:
(define_insn_and_split "*<any_extract:optab><GPR:mode>3"
[(set (match_operand:GPR 0 "register_operand" "=r")
(any_extract:GPR
(match_operand:GPR 1 "register_operand" " r")
(match_operand 2 "const_int_operand")
(match_operand 3 "const_int_operand")))
(clobber (match_scratch:GPR 4 "=&r"))]
"..omitted.."
"#"
"&& reload_completed"
[(set (match_dup 4)
(ashift:GPR (match_dup 1) (match_dup 2)))
(set (match_dup 0)
(<extract_shift>:GPR (match_dup 4) (match_dup 3)))]
This might be less of an issue since GCC 16 now that there is logic that tries
to use the same destination register in RA/regrename for fused pairs. Perhaps
the `reload_completed` needs to be ditched here, might give better results.
Best regards,
Michiel