This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

reload.c and doubly-indirect memory references


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.)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]