overridden optional reload may cause a needed reload to be dropped

Alexandre Oliva aoliva@redhat.com
Wed Oct 25 01:23:00 GMT 2000


The following sequence of insns (from which several intervening
irrelevant insns have been omitted) exposes a problem in reload on SH.
Unfortunately, the original testcase is part of a commercial
testsuite, so I can't post it.

(insn 5952 5950 5953 (parallel[ 
            (set (reg:SF 2282)
                (const_double:SF (const_int 0 [0x0]) 0 [0x0] 1076887552 [0x40300000] [16]))
...
(insn 7470 7454 7472 (parallel[
            (set (reg:SF 2849)
                (reg:SF 2282))
...
(insn 7500 7495 19452 (parallel[ 
            (set (reg:DF 2863)
                (float_extend:DF (reg:SF 2849)))

(insn 19452 7500 19638 (parallel[
            (set (reg:SF 2861)
                (reg:SF 2849))
 
The constant in insn 5952 ends up being loaded into fr1.  Pseudo 2849
is assigned stack slot @(6416,r14), so reload loads 6416 into r0 for
insn 7470, and copies fr1 to @(r0,r14).  So far so good.

Insn 7500 requires fr1 to be copied to fpul, so that it can be
extended to double to fr4.  And here comes the problem.  At the end of
choose_reload_regs() for insn 19452, we have:

(set (reg:SF 25 fr1) (mem:SF (plus:SF (reg:SI 14 r14) (const_int 6416))))

Reloads for insn # 19452
Reload 0: R0_REGS, RELOAD_FOR_OPERAND_ADDRESS (opnum = 1)
        reload_in_reg: (const_int 6416 [0x1910])
Reload 1: reload_in (SF) = (reg:SF 22 fpul)
        FP_REGS, RELOAD_FOR_INPUT (opnum = 1), optional, can't combine
        reload_in_reg: (reg:SF 2849)

choose_reload_regs() had correctly determined that the constant 6416
could be re-used from the reloads for 7470.  However, the loop that
removes ``reloads needed for reloads that can be inherited'' decides
to discard it because of reload 1:

	  else if (rld[r].in
		   && rld[r].out != rld[r].in
		   && remove_address_replacements (rld[r].in) && pass)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^

The problem is that, since the reload is optional but isn't inherited,
it ends up not taking place, and the invalid address @(6416,r14) makes
it to the assembly output.

The solution I've found for this problem is to arrange for optional
reloads that cause other reloads to be dropped to become inherited
reloads, unless they're dropped by other reloads.  Here's the patch
I've come up with.  Ok to install?  (bootstrap completed on
i686-pc-linux-gnu; x-sh-elf target libraries built; currently running
the testsuite)



More information about the Gcc-patches mailing list