As discussed on the PR
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70751,
here is the patch.
For this particular failure on arm, *arm_movsi_insn has the following operand
constraints:
operand 0: "=rk,r,r,r,rk,m"
operand 1: "rk, I,K,j,mi,rk"
gcc won't explicitly refuse an unmatch CT_MEMORY operand (r235184) if it
comes from substituion that alternative (alt) 4 got a chance to compete with
alt 0, and eventually be the winner as it's with rld_nregs=0 while alt 0 is
with rld_nregs=1.
I fell it's OK to give alt 4 a chance here, but we should calculate the cost
correctly.
For alt 4, it should be treated as spill into memory, but currently lra only
recognize a spill for pseudo register. While the spilled rtx for alt 4 is a
plus after equiv substitution.
(plus:SI (reg/f:SI 102 sfp)
(const_int 4 [0x4]))
This patch thus let lra-constraint cost spill of Non-pseudo as well and fixed
the regression.
x86_64/aarch64/arm boostrap and regression OK.
arm bootstrapped cc1 is about 0.3% smaller in code size.
OK for trunk?
gcc/
PR rtl-optimization/70751
* lra-constraints.c (process_alt_operands): Recognize Non-pseudo
spilled into
memory.
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index e4e6c8c..8f2db87 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -2474,14 +2474,29 @@ process_alt_operands (int only_alternative)
/* We are trying to spill pseudo into memory. It is
usually more costly than moving to a hard register
although it might takes the same number of
- reloads. */
- if (no_regs_p && REG_P (op) && hard_regno[nop] >= 0)
+ reloads.
+
+ PR 70751, non-pseudo spill may happen also. For example, if an
+ operand comes from equiv substitution, then we won't reject it
+ if it's an unmatch CT_MEMORY in above code (see r235184).
+ Suppose a target allows both register and memory in the
+ operand constraint alternatives, then it's typical that an
+ eliminable register has a substition of "base + offset" which
+ can either be reloaded by a simple "new_reg <= base + offset"
+ which will match the register constraint, or a similar reg
+ addition followed by further spill to and reload from memory
+ which will match the memory constraint, but this memory spill
+ will be much more costly usually.
+
+ Code below increases the reject for both pseudo and non-pseudo
+ spill. */
+ if (no_regs_p && !(REG_P (op) && hard_regno[nop] < 0))
{
if (lra_dump_file != NULL)
fprintf
(lra_dump_file,
- " %d Spill pseudo into memory: reject+=3\n",
- nop);
+ " %d Spill %spseudo into memory: reject+=3\n",
+ nop, REG_P (op) ? "" : "Non-");
reject += 3;
if (VECTOR_MODE_P (mode))
{