https://gcc.gnu.org/g:21251fe7ff5cee3b899ebc79a4c421c89f439d34

commit r16-3240-g21251fe7ff5cee3b899ebc79a4c421c89f439d34
Author: Artemiy Volkov <artem...@acm.org>
Date:   Sun Aug 17 08:08:29 2025 -0600

    regrename: treat writes as reads for fused instruction pairs
    
    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.

Diff:
---
 gcc/regrename.cc | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/gcc/regrename.cc b/gcc/regrename.cc
index 7de88812e4cb..cb03c1d71dd0 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;)

Reply via email to