http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52804

--- Comment #1 from amker.cheng <amker.cheng at gmail dot com> 2012-04-03 
16:43:30 UTC ---
For insns before ira:


(insn 82 81 83 3 (set (reg/f:SI 281 [ *o_15(D) ])
        (mem/f:SI (reg/v/f:SI 315 [orig:275 o ] [275]) [2 *o_15(D)+0 S4 A32]))
pr52804.c:18 186 {*thumb1_movsi_insn}
     (expr_list:REG_EQUIV (mem/f:SI (reg/v/f:SI 315 [orig:275 o ] [275]) [2
*o_15(D)+0 S4 A32])
        (nil)))

(insn 83 82 84 3 (set (reg/v/f:SI 198 [ o0 ])
        (mem/f:SI (plus:SI (reg/f:SI 281 [ *o_15(D) ])
                (reg:SI 273 [ D.4183 ])) [2 *D.4088_18+0 S4 A32])) pr52804.c:18
186 {*thumb1_movsi_insn}
     (expr_list:REG_DEAD (reg/f:SI 281 [ *o_15(D) ])
        (nil)))

(insn 84 83 85 3 (set (reg/f:SI 282 [ MEM[(char * * *)o_15(D) + 4B] ])
        (mem/f:SI (plus:SI (reg/v/f:SI 315 [orig:275 o ] [275])
                (const_int 4 [0x4])) [2 MEM[(char * * *)o_15(D) + 4B]+0 S4
A32])) pr52804.c:19 186 {*thumb1_movsi_insn}
     (expr_list:REG_EQUIV (mem/f:SI (plus:SI (reg/v/f:SI 315 [orig:275 o ]
[275])
                (const_int 4 [0x4])) [2 MEM[(char * * *)o_15(D) + 4B]+0 S4
A32])
        (nil)))

(insn 85 84 171 3 (set (reg/v/f:SI 201 [ o1 ])
        (mem/f:SI (plus:SI (reg/f:SI 282 [ MEM[(char * * *)o_15(D) + 4B] ])
                (reg:SI 273 [ D.4183 ])) [2 *D.4091_23+0 S4 A32])) pr52804.c:19
186 {*thumb1_movsi_insn}
     (expr_list:REG_DEAD (reg/f:SI 282 [ MEM[(char * * *)o_15(D) + 4B] ])
        (expr_list:REG_DEAD (reg:SI 273 [ D.4183 ])
            (nil))))

The registers allocated are:
r315 -> r9
r281 -> mem
r273 -> r3
r198 -> r12
r201 -> r7

The insns need reload are like:
insn 82 (deleted)
insn 84 (deleted)
insn 83
insn 85

The corresponding dump info of reload pass is like:

Reloads for insn # 83
Reload 0: reload_in (SI) = (reg/v/f:SI 9 r9 [orig:275 o ] [275])
    BASE_REGS, RELOAD_FOR_INPADDR_ADDRESS (opnum = 1)
    reload_in_reg: (reg/v/f:SI 9 r9 [orig:275 o ] [275])
    reload_reg_rtx: (reg:SI 6 r6)
Reload 1: reload_in (SI) = (mem/f:SI (reg/v/f:SI 9 r9 [orig:275 o ] [275]) [2
*o_15(D)+0 S4 A32])
    LO_REGS, RELOAD_FOR_INPUT_ADDRESS (opnum = 1), can't combine
    reload_in_reg: (reg/f:SI 281 [ *o_15(D) ])
    reload_reg_rtx: (reg:SI 6 r6)
Reload 2: LO_REGS, RELOAD_FOR_INPUT_ADDRESS (opnum = 1), can't combine,
secondary_reload_p
    reload_reg_rtx: (reg:SI 7 r7)
Reload 3: reload_in (SI) = (mem/f:SI (plus:SI (reg/f:SI 281 [ *o_15(D) ])
                                                        (reg:SI 3 r3 [orig:273
D.4183 ] [273])) [2 *D.4088_18+0 S4 A32])
    CORE_REGS, RELOAD_FOR_INPUT (opnum = 1)
    reload_in_reg: (mem/f:SI (plus:SI (reg/f:SI 281 [ *o_15(D) ])
                                                        (reg:SI 3 r3 [orig:273
D.4183 ] [273])) [2 *D.4088_18+0 S4 A32])
    reload_reg_rtx: (reg/v/f:SI 12 ip [orig:198 o0 ] [198])
    secondary_in_reload = 2

Reloads for insn # 85
Reload 0: reload_in (SI) = (reg/v/f:SI 9 r9 [orig:275 o ] [275])
    BASE_REGS, RELOAD_FOR_OPADDR_ADDR (opnum = 1)
    reload_in_reg: (reg/v/f:SI 9 r9 [orig:275 o ] [275])
    reload_reg_rtx: (reg:SI 6 r6)
Reload 1: reload_in (SI) = (mem/f:SI (plus:SI (reg/v/f:SI 9 r9 [orig:275 o ]
[275])
                                                        (const_int 4 [0x4])) [2
MEM[(char * * *)o_15(D) + 4B]+0 S4 A32])
    LO_REGS, RELOAD_FOR_OPERAND_ADDRESS (opnum = 1), can't combine
    reload_in_reg: (reg/f:SI 282 [ MEM[(char * * *)o_15(D) + 4B] ])
    reload_reg_rtx: (reg:SI 0 r0)

We can see, after reload, insn sequence for insn 83/85 shoud be like:
insn 83:
  r6 = r9
  r6 = [r6]
  r7 = [r6 + r3]
  r12 = r7
insn 85:
  r6 = r9
  r0 = [r6 + 4]
  r7 = [r0 + r3]

***BUT***
The problem is:
RELOAD forms wrong inherited information when reloading insn 83, i.e., reload
assumes that r9 is reloaded in r6 and is valid for inheriting when reloading
insn 85. Resulting in using r6, which has already been corrupted.

After looking into reload. I think function reload_reg_reaches_end_p has missed
following case:
rld[0]
  in : r9
  reg_rtx : r6
  when_needed : RELOAD_FOR_INPADDR_ADDRESS
rld[1]
  in : [r9]
  reg_rtx : r6
  when_neede : RELOAD_FOR_INPUT_ADDRESS

In this case, the call of "reload_reg_reaches_end_p(regno(=6), reloadnum(=0))"
should return 0, rather than 1 as now. because r6 used in rld[0] is corrupted
by rld[1].

Reply via email to