From: Artemiy Volkov <arte...@synopsys.com> Consider the following (RISC-V) instruction pair:
mul s6,a1,a2 add s6,a4,s6 Without this patch, while handling the second instruction, (a) the existing chain for s6 will first be closed (upon the terminate_write action for the input operand), then (b) a new one will be opened (upon the mark_write action for the output operand). This will likely lead to the two output operands being different physical registers, breaking the single-output property required for some macro-op fusion pairs. This patch, using the single_output_fused_pair_p () predicate introduced earlier, changes the regrename behavior for such pairs to append the input and the output operands to the existing chain (as if both actions were mark_read), instead of breaking the current renaming chain and starting a new one. This ensures that the output operands of both fused instructions are kept in the same hard register, and that the single-output property of the insn pair is preserved. gcc/ChangeLog: * regrename.cc (scan_rtx_reg): Handle fused insn pairs. Signed-off-by: Artemiy Volkov <arte...@synopsys.com> --- gcc/regrename.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/gcc/regrename.cc b/gcc/regrename.cc index 7de88812e4c..cb03c1d71dd 100644 --- a/gcc/regrename.cc +++ b/gcc/regrename.cc @@ -1117,6 +1117,12 @@ scan_rtx_reg (rtx_insn *insn, rtx *loc, enum reg_class cl, enum scan_actions act unsigned this_regno = REGNO (x); int this_nregs = REG_NREGS (x); + /* Do not process write actions for the second instruction of + a macro-fused pair of two single_sets. */ + if ((action == mark_write || action == terminate_write) + && single_output_fused_pair_p (insn)) + return; + if (action == mark_write) { if (type == OP_OUT) @@ -1153,7 +1159,9 @@ scan_rtx_reg (rtx_insn *insn, rtx *loc, enum reg_class cl, enum scan_actions act return; } - if ((type == OP_OUT) != (action == terminate_write || action == mark_access)) + if ((type == OP_OUT) != (action == terminate_write || action == mark_access) + && ! (type == OP_OUT && action == mark_read + && single_output_fused_pair_p (insn))) return; for (p = &open_chains; *p;) -- 2.43.0