reload.c and doubly-indirect memory references

Pip Cet pipcet@gmail.com
Sun Feb 28 20:21:00 GMT 2016


I'm having trouble with a (very) experimental port and doubly-indirect
memory references. What happens is that during reload, RTL that looks
like this:

(insn 226 225 228 30 (set (mem/f:SI (mem/f:SI (plus:SI (reg/v/f:SI 91
[ listop ])
                    (const_int 20 [0x14])) [19 listop_90->op_first+0
S4 A32]) [19 _92->op_next+0 S4 A32])
        (mem/f:SI (reg/v/f:SI 86 [ range ]) [19 range_81->op_next+0 S4
A32])) op.c:7362 6 {*assignsi}
     (nil))

(which is correct) turns into this:

(insn 419 225 420 30 (set (reg:SI 9 r1)
        (mem/c:SI (plus:SI (reg/f:SI 0 fp)
                (const_int -16 [0xfffffffffffffff0])) [179 %sfp+-16 S4
A32])) op.c:7362 6 {*assignsi}
     (nil))
(insn 420 419 226 30 (set (reg:SI 9 r1)
        (mem/c:SI (plus:SI (reg/f:SI 0 fp)
                (const_int -4 [0xfffffffffffffffc])) [179 %sfp+-4 S4
A32])) op.c:7362 6 {*assignsi}
     (nil))
(insn 226 420 228 30 (set (mem/f:SI (mem/f:SI (plus:SI (reg:SI 9 r1)
                    (const_int 20 [0x14])) [19 listop_90->op_first+0
S4 A32]) [19 _92->op_next+0 S4 A32])
        (mem/f:SI (reg:SI 9 r1) [19 range_81->op_next+0 S4 A32]))
op.c:7362 6 {*assignsi}
     (nil))

(which is incorrect as register r1 is used to reload two different values).

Indeed, the debug output clarifies that what is happening is that two
operands are reloaded using the same register:

Spilling for insn 226.
Using reg 9 for reload 0
Using reg 9 for reload 1

Reloads for insn # 226
Reload 0: reload_in (SI) = (reg/v/f:SI 91 [ listop ])
    GENERAL_REGS, RELOAD_FOR_OPADDR_ADDR (opnum = 0)
    reload_in_reg: (reg/v/f:SI 91 [ listop ])
    reload_reg_rtx: (reg:SI 9 r1)
Reload 1: reload_in (SI) = (reg/v/f:SI 86 [ range ])
    GENERAL_REGS, RELOAD_FOR_OPERAND_ADDRESS (opnum = 1)
    reload_in_reg: (reg/v/f:SI 86 [ range ])
    reload_reg_rtx: (reg:SI 9 r1)

...and this is where I get stuck. I'm not sure whether the reload
types are correct at all: should both operands have .when_needed =
RELOAD_FOR_INPUT? Or should RELOAD_FOR_OPADDR_ADDR be made to conflict
with RELOAD_FOR_OPERAND_ADDRESS in reload1.c:reloads_conflict? In
other words, is RELOAD_FOR_OPADDR_ADDR reserved for reloads of
registers used in reloads of address registers (as the name of the
reload_reg_used_in_op_addr_reload variable seems to imply), or does it
apply equally in this case?

(Of course it's easy enough to disallow doubly-indirect references in
TARGET_LEGITIMATE_ADDRESS_P, so I can work around this for now, but it
would still be nice to understand.)



More information about the Gcc-help mailing list