Bernd Schmidt wrote:
Mark Shinwell wrote:
The bug is currently only exhibiting itself on a proprietary testcase
when compiled for an ARM target and is extremely sensitive to the
particular code involved.  It arises as follows, using the same notation
as in Richard's mail:

If you can't post the testcase, the best thing you can do to help is to
print out all the involved RTL insns before and after, as well as output
from debug_reload for all of them (possibly once after returning to
reload_as_needed from find_reloads, and again after choose_reload_regs
has run).

The relevant RTL instructions before reload are as follows.  These
correspond to points A, B and C respectively in my previous email.

(insn:HI 5301 3071 3079 2 (set (reg/f:SI 4082)
        (reg/f:SI 3275)) 572 {*arm_movsi_vfp} (nil)
    (expr_list:REG_EQUIV (symbol_ref:SI ("*.LANCHOR0") [flags 0x182])
        (nil)))
---
(insn:HI 5291 5282 5295 2 (set (reg:DF 4078 [ Jd+1040 ])
        (mem/s:DF (plus:SI (reg/f:SI 3275)
                (reg:SI 3812)) [30 Jd+1040 S8 A64])) 578 {*movdf_vfp} (nil)
    (expr_list:REG_DEAD (reg/f:SI 3275)
        (expr_list:REG_DEAD (reg:SI 3812)
            (nil))))
---
(insn:HI 5314 5308 5318 2 (set (reg:DF 4096 [ Jd+1040 ])
        (mem/s:DF (plus:SI (reg/f:SI 4082)
                (reg:SI 4084)) [30 Jd+1040 S8 A64])) 578 {*movdf_vfp} (nil)
    (expr_list:REG_EQUIV (mem/s:DF (plus:SI (reg/f:SI 4082)
                (reg:SI 4084)) [30 Jd+1040 S8 A64])
        (nil)))

After reload we end up with the following.  I've added dividers to show
the correspondence with the insns above.

(insn:HI 5301 3071 3079 2 (set (mem/f/c:SI (plus:SI (reg/f:SI 13 sp)
                (const_int 12 [0xc])) [36 S4 A32])
        (reg/f:SI 9 r9 [3275])) 572 {*arm_movsi_vfp} (nil)
    (expr_list:REG_EQUIV (symbol_ref:SI ("*.LANCHOR0") [flags 0x182])
        (nil)))
---
(insn 6675 5282 5291 2 (set (reg:SI 9 r9)
        (plus:SI (reg/f:SI 9 r9 [3275])
            (reg:SI 10 sl [3812]))) 4 {*arm_addsi3} (nil)
    (nil))

(insn:HI 5291 6675 5295 2 (set (reg:DF 75 s12 [orig:4078 Jd+1040 ] [4078])
        (mem/s:DF (reg:SI 9 r9) [30 Jd+1040 S8 A64])) 578 {*movdf_vfp} (nil)
    (nil))
---
(insn 6680 5308 6681 2 (set (reg:SI 1 r1)
        (const_int 4928 [0x1340])) 572 {*arm_movsi_vfp} (nil)
    (nil))

(insn 6681 6680 5314 2 (set (reg:SI 1 r1)
        (plus:SI (reg/f:SI 9 r9 [3275])
            (reg:SI 1 r1))) 4 {*arm_addsi3} (nil)
    (nil))

(insn:HI 5314 6681 5318 2 (set (reg:DF 75 s12 [orig:4096 Jd+1040 ] [4096])
        (mem/s:DF (reg:SI 1 r1) [30 Jd+1040 S8 A64])) 578 {*movdf_vfp} (nil)
    (expr_list:REG_EQUIV (mem/s:DF (reg:SI 1 r1) [30 Jd+1040 S8 A64])
        (nil)))

We see here how pseudo 3275 was allocated to r9 and pseudo 4082 was
spilled to the stack.  At insn 5291, r9 has been allocated [*] as the
reload register since pseudo 3275 dies in that instruction; at insn
5314 we see the then-incorrect use of r9 (in instruction 6681)
for the value of pseudo 4082.  Note also how the dump shows that the
compiler thinks r9 still holds the value of pseudo 3275 at insn 6681.

The reloads and the values of the "insn" variable in reload_as_needed
are as follows.  These have been dumped at the points you suggest
(the output after choose_reload_regs being the same as after
find_reloads).

For instruction 5301:

(insn:HI 5301 3071 3079 2 (set (reg/f:SI 4082)
        (reg/f:SI 9 r9 [3275])) 572 {*arm_movsi_vfp} (nil)
    (expr_list:REG_EQUIV (symbol_ref:SI ("*.LANCHOR0") [flags 0x182])
        (nil)))
Reload 0: reload_out (SI) = (reg/f:SI 4082)
        NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
        reload_out_reg: (reg/f:SI 4082)

For instruction 5291:

(insn:HI 5291 5282 5295 2 (set (reg:DF 75 s12 [orig:4078 Jd+1040 ] [4078])
        (mem/s:DF (plus:SI (reg/f:SI 9 r9 [3275])
(reg:SI 10 sl [3812])) [30 Jd+1040 S8 A64])) 578 {*movdf_vfp} (nil)
    (expr_list:REG_DEAD (reg/f:SI 9 r9 [3275])
        (expr_list:REG_DEAD (reg:SI 10 sl [3812])
            (nil))))
Reload 0: reload_in (SI) = (plus:SI (reg/f:SI 9 r9 [3275])
                                                    (reg:SI 10 sl [3812]))
        GENERAL_REGS, RELOAD_FOR_INPUT (opnum = 1), inc by 8
        reload_in_reg: (plus:SI (reg/f:SI 9 r9 [3275])
                                                    (reg:SI 10 sl [3812]))
        reload_reg_rtx: (reg:SI 9 r9)

For instruction 5314:

(insn:HI 5314 5308 5318 2 (set (reg:DF 75 s12 [orig:4096 Jd+1040 ] [4096])
        (mem/s:DF (plus:SI (reg/f:SI 4082)
                (reg:SI 4084)) [30 Jd+1040 S8 A64])) 578 {*movdf_vfp} (nil)
    (expr_list:REG_EQUIV (mem/s:DF (plus:SI (reg/f:SI 4082)
                (reg:SI 4084)) [30 Jd+1040 S8 A64])
        (nil)))
Reload 0: reload_in (SI) = (reg/f:SI 4082)
        GENERAL_REGS, RELOAD_FOR_INPUT_ADDRESS (opnum = 1)
        reload_in_reg: (reg/f:SI 4082)
Reload 1: reload_in (SI) = (const_int 4928 [0x1340])
        GENERAL_REGS, RELOAD_FOR_INPUT_ADDRESS (opnum = 1), can't combine
        reload_in_reg: (reg:SI 4084)
Reload 2: reload_in (SI) = (plus:SI (reg/f:SI 4082)
                                                    (reg:SI 4084))
        GENERAL_REGS, RELOAD_FOR_INPUT (opnum = 1), inc by 8
        reload_in_reg: (plus:SI (reg/f:SI 4082)
                                                    (reg:SI 4084))

These dumps are of course taken before the application of my patch.

Hope that helps,
Mark

[*] I believe that judgement comes from reload.c:push_reload as
explained by the following comment:

  /* If this is an input reload and the operand contains a register that
     dies in this insn and is used nowhere else, see if it is the right
     class to be used for this reload.  Use it if so.  (This occurs most
     commonly in the case of paradoxical SUBREGs and in-out reloads).  We
     cannot do this if it is also an output reload that mentions the
     register unless the output is a SUBREG that clobbers an entire
     register.

     Note that the operand might be one of the spill regs, if it is a
     pseudo reg and we are in a block where spilling has not taken place.
     But if there is no spilling in this block, that is OK.
     An explicitly used hard reg cannot be a spill reg.  */

Reply via email to