------- Comment #5 from hjl dot tools at gmail dot com 2008-11-28 21:11 ------- do_input_reload has
if (optimize && reload_inherited[j] && rl->in && MEM_P (rl->in) && MEM_P (rl->in_reg) && reload_spill_index[j] >= 0 && TEST_HARD_REG_BIT (reg_reloaded_valid, reload_spill_index[j])) rl->in = regno_reg_rtx[reg_reloaded_contents[reload_spill_index[j]]]; (gdb) call debug_rtx (insn) (insn 151 47 48 3 /tmp/foo.f90:6 (set (reg:SI 1 dx [87]) (mem/u/c:SI (const:SI (unspec:SI [ (symbol_ref:SI ("__threadprivate2_MOD_foo") [flags 0x60] <var_decl 0x7ffff7fd3780 foo>) ] 8)) [0 S4 A8])) 47 {*movsi_1} (expr_list:REG_EQUIV (mem/u/c:SI (const:SI (unspec:SI [ (symbol_ref:SI ("__threadprivate2_MOD_foo") [flags 0x60] <var_decl 0x7ffff7fd3780 foo>) ] 8)) [0 S4 A8]) (nil))) (gdb) p *rl $6 = {in = 0x7ffff7e959c0, out = 0x0, rclass = GENERAL_REGS, inmode = SImode, outmode = VOIDmode, mode = SImode, nregs = 1, inc = 0, in_reg = 0x7ffff7e959c0, out_reg = 0x0, regno = -1, reg_rtx = 0x7ffff7e819c0, opnum = 1, secondary_in_reload = -1, secondary_out_reload = -1, secondary_in_icode = CODE_FOR_nothing, secondary_out_icode = CODE_FOR_nothing, when_needed = RELOAD_FOR_INPUT, optional = 1, nocombine = 0, secondary_p = 0, nongroup = 0} (gdb) call debug_rtx (rl->in) (mem/u/c:SI (const:SI (unspec:SI [ (symbol_ref:SI ("__threadprivate2_MOD_foo") [flags 0x60] <var_decl 0x7ffff7fd3780 foo>) ] 8)) [0 S4 A8]) (gdb) call debug_rtx (rl->in_reg) (mem/u/c:SI (const:SI (unspec:SI [ (symbol_ref:SI ("__threadprivate2_MOD_foo") [flags 0x60] <var_decl 0x7ffff7fd3780 foo>) ] 8)) [0 S4 A8]) (gdb) call debug_rtx (rl->reg_rtx) (reg:SI 2 cx [80]) (gdb) p reload_spill_index[j] $7 = 1 (gdb) It replaces rl->in with an reg_rtx different from rl->reg_rtx and confused IRA. I don't know if it is a reload or IRA bug. This patch fixes the testcase. --- reload1.c.foo 2008-11-21 06:06:55.000000000 -0800 +++ reload1.c 2008-11-28 12:56:54.000000000 -0800 @@ -7508,6 +7508,8 @@ do_input_reload (struct insn_chain *chai && MEM_P (rl->in) && MEM_P (rl->in_reg) && reload_spill_index[j] >= 0 + && (rl->reg_rtx == 0 + || REGNO (rl->reg_rtx) == (unsigned int) reload_spill_index[j]) && TEST_HARD_REG_BIT (reg_reloaded_valid, reload_spill_index[j])) rl->in = regno_reg_rtx[reg_reloaded_contents[reload_spill_index[j]]]; -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38272