https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70416

--- Comment #23 from Oleg Endo <olegendo at gcc dot gnu.org> ---
(In reply to Oleg Endo from comment #21)
> I'll see if there's some other way...

With the patch below, I get

sum:  3342539 -> 3342639    +100 / +0.002992 %

for the CSiBE set.  The increases are because r14 is used as an alias for r15
and the extra checks in the pattern only look for r15.  However, it seems that
for most cases it's good enough the code size increases as mentioned in comment
#18.

I guess the proper solution for this issue would be running an
address-mode-selection optimization pass after reload to fix up the reload
choices.  Probably it would also be beneficial when using LRA.

I'm now re-testing the patch on sh-elf.

Index: gcc/config/sh/sh.md
===================================================================
--- gcc/config/sh/sh.md (revision 234506)
+++ gcc/config/sh/sh.md (working copy)
@@ -2242,14 +2242,23 @@
   [(set_attr "type" "arith")])

 ;; Old reload might generate add insns directly (not through the expander) for
-;; the memory address of complex insns like atomic insns when reloading.
+;; address register calculations when reloading, in which case it won't try
+;; the addsi_scr pattern.  Because reload will sometimes try to validate
+;; the generated insns and their constraints, this pattern must be
+;; recognizable during and after reload.  However, when reload generates
+;; address register calculations for the stack pointer, we don't allow this
+;; pattern.  This will make reload prefer using indexed @(reg + reg) address
+;; modes when the displacement of a @(disp + reg) doesn't fit.
 (define_insn_and_split "*addsi3"
   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
        (plus:SI (match_operand:SI 1 "arith_reg_operand" "r")
                 (match_operand:SI 2 "arith_or_int_operand" "rn")))]
   "TARGET_SH1 && !sh_lra_p ()
-   && reload_completed
-   && !reg_overlap_mentioned_p (operands[0], operands[1])"
+   && (reload_completed || reload_in_progress)
+   && !reg_overlap_mentioned_p (operands[0], operands[1])
+   && (!reload_in_progress
+       || ((!REG_P (operands[1]) || REGNO (operands[1]) != SP_REG)
+          && (!REG_P (operands[2]) || REGNO (operands[2]) != SP_REG)))"
   "#"
   "&& 1"
   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]

Reply via email to