One consequence of r276318 was that cselib now preserves sp-based
values across function calls.  This in turn convinced cprop to
replace the clobber in:

   (set (reg PSUEDO) (reg sp))
   ...
   (call ...)
   ...
   (clobber (mem:BLK (reg sp)))

with:

   (clobber (mem:BLK (reg PSEUDO)))

But I doubt this could ever be an optimisation, regardless of what the
changed instruction is.  Extending the lifetimes of pseudos can lead to
extra spills, whereas sp is available everywhere.

More generally, I don't think we should replace any fixed hard register
with a pseudo.  Replacing them with a constant is still potentially
useful though, since we'll only make the change if the insn pattern
allows it.

This part 1 of the fix for PR93124.  Part 2 contains the testcase.

Tested on aarch64-linux-gnu and x86_64-linux-gnu.  OK to install?

Richard


2020-01-22  Richard Sandiford  <richard.sandif...@arm.com>

gcc/
        PR rtl-optimization/93124
        * cprop.c (cprop_replace_with_reg_p): New function.
        (cprop_insn, do_local_cprop): Use it.
---
 gcc/cprop.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/gcc/cprop.c b/gcc/cprop.c
index 169ca804e33..5f6446984d8 100644
--- a/gcc/cprop.c
+++ b/gcc/cprop.c
@@ -261,6 +261,18 @@ cprop_reg_p (const_rtx x)
   return REG_P (x) && !HARD_REGISTER_P (x);
 }
 
+/* Return true if it is worth replacing register REGNO with a different
+   register.  */
+
+static bool
+cprop_replace_with_reg_p (unsigned int regno)
+{
+  /* Replacing a fixed register with a pseudo can lead to extra spilling.
+     If REGNO is eliminable, replacing it could also lead to less efficient
+     eliminations.  */
+  return !HARD_REGISTER_NUM_P (regno) || !fixed_regs[regno];
+}
+
 /* Scan SET present in INSN and add an entry to the hash TABLE.
    IMPLICIT is true if it's an implicit set, false otherwise.  */
 
@@ -1098,6 +1110,7 @@ cprop_insn (rtx_insn *insn)
          /* Copy propagation.  */
          else if (src_reg && cprop_reg_p (src_reg)
                   && REGNO (src_reg) != regno
+                  && cprop_replace_with_reg_p (regno)
                   && try_replace_reg (reg_used, src_reg, insn))
            {
              changed_this_round = changed = 1;
@@ -1198,6 +1211,7 @@ do_local_cprop (rtx x, rtx_insn *insn)
          if (cprop_constant_p (this_rtx))
            newcnst = this_rtx;
          if (cprop_reg_p (this_rtx)
+             && cprop_replace_with_reg_p (REGNO (x))
              /* Don't copy propagate if it has attached REG_EQUIV note.
                 At this point this only function parameters should have
                 REG_EQUIV notes and if the argument slot is used somewhere
-- 
2.17.1

Reply via email to