I've got a bug with gcc-3.4.6 (also with 3.3.2, 3.3.6, probably
anything inbetween), target sh-elf. Unfortunately, the test case is
huge, convoluted and proprietary, so I can't send it for now.
When reloading insn 2780:
Breakpoint 3, reload_as_needed (live_known=1)
at ../../gcc-3.4.6/gcc/reload1.c:3802
(gdb) p insn
$3 = (rtx) 0x2aaaab202910
(gdb) call debug_rtx (insn)
(insn:HI 2780 2777 2782 1 (set (reg/f:SI 1726)
(plus:SI (reg/f:SI 1706)
(const_int 4 [0x4]))) 23 {*addsi3_compact} (nil)
(nil))
(gdb) call debug_rtx (reg_equiv_memory_loc [1726])
(mem:SI (plus:SI (reg/f:SI 14 r14)
(const_int 156 [0x9c])) [16 S4 A32])
After calling ``eliminate_regs_in_insn()'':
(gdb) call debug_rtx (insn)
(insn:HI 2780 2777 2782 1 (set (reg/f:SI 1726)
(plus:SI (plus:SI (reg/f:SI 14 r14)
(const_int 124 [0x7c]))
(const_int 4 [0x4]))) 23 {*addsi3_compact} (nil)
(nil))
After calling ``find_reloads()'' and ``choose_reload_regs()'':
(gdb) call debug_reload ()
Reload 0: reload_in (SI) = (plus:SI (reg/f:SI 14 r14)
(const_int 124 [0x7c]))
reload_out (SI) = (mem:SI (plus:SI (plus:SI (reg/f:SI 14 r14)
(const_int 124 [0x7c]))
(const_int 32 [0x20])) [16 S4 A32])
GENERAL_REGS, RELOAD_OTHER (opnum = 0)
reload_in_reg: (plus:SI (reg/f:SI 14 r14)
(const_int 124 [0x7c]))
reload_out_reg: (reg/f:SI 1726)
reload_reg_rtx: (reg:SI 3 r3)
(gdb) call debug_rtx (insn)
(insn:HI 2780 2777 2782 1 (set (mem:SI (plus:SI (plus:SI (reg/f:SI 14 r14)
(const_int 124 [0x7c]))
(const_int 32 [0x20])) [16 S4 A32])
(plus:SI (plus:SI (reg/f:SI 14 r14)
(const_int 124 [0x7c]))
(const_int 4 [0x4]))) 23 {*addsi3_compact} (nil)
(nil))
After calling ``emit_reload_insns()'' the relevant insns are:
(insn 22940 2777 22941 1 (set (reg:SI 3 r3)
(const_int 124 [0x7c])) -1 (nil)
(nil))
(insn 22941 22940 2780 1 (set (reg:SI 3 r3)
(plus:SI (reg:SI 3 r3)
(reg/f:SI 14 r14))) 23 {*addsi3_compact} (nil)
(expr_list:REG_EQUIV (plus:SI (reg/f:SI 14 r14)
(const_int 124 [0x7c]))
(nil)))
(insn:HI 2780 22941 22942 1 (set (mem:SI (plus:SI (plus:SI (reg/f:SI 14 r14)
(const_int 124 [0x7c]))
(const_int 32 [0x20])) [16 S4 A32])
(plus:SI (plus:SI (reg/f:SI 14 r14)
(const_int 124 [0x7c]))
(const_int 4 [0x4]))) 23 {*addsi3_compact} (nil)
(nil))
(insn 22942 2780 2782 1 (set (mem:SI (plus:SI (plus:SI (reg/f:SI 14 r14)
(const_int 124 [0x7c]))
(const_int 32 [0x20])) [16 S4 A32])
(reg:SI 3 r3)) -1 (nil)
(nil))
So far so good. Note that in insn 22942, r3 is saved in [r14 + 156].
However, after calling ``subst_reloads()'', the insns become:
(insn 22940 2777 22941 1 (set (reg:SI 3 r3)
(const_int 124 [0x7c])) -1 (nil)
(nil))
(insn 22941 22940 2780 1 (set (reg:SI 3 r3)
(plus:SI (reg:SI 3 r3)
(reg/f:SI 14 r14))) 23 {*addsi3_compact} (nil)
(expr_list:REG_EQUIV (plus:SI (reg/f:SI 14 r14)
(const_int 124 [0x7c]))
(nil)))
(insn:HI 2780 22941 22942 1 (set (reg:SI 3 r3)
(plus:SI (reg:SI 3 r3)
(const_int 4 [0x4]))) 23 {*addsi3_compact} (nil)
(nil))
(insn 22942 2780 2782 1 (set (mem:SI (plus:SI (reg:SI 3 r3)
(const_int 32 [0x20])) [16 S4 A32])
(reg:SI 3 r3)) -1 (nil)
(nil))
Now r3 is stored at [r14 + 160], which is incorrect. The reason is
that when substituting the reload register into insn 2780, the insn
22942 is modified also, because they share the following rtx: (plus:SI
(reg/f:SI 14 r14) (const_int 124 [0x7c])). Since insn 2780 modifies
r3, r3 is no longer equal to ``r14 + 124'' at insn 22942, which
results in incorrect store.
I'd appreciate any suggestions for fixing this.
~velco