http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56184
Ulrich Weigand <uweigand at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |vmakarov at gcc dot gnu.org
--- Comment #6 from Ulrich Weigand <uweigand at gcc dot gnu.org> 2013-02-06
19:40:30 UTC ---
The problem occurs with the following insn:
(insn 539 383 384 46
(set (reg:DI 355 [313]) (const_int 256 [0x100]))
test.ii:128 643 {*movdi_vfp}
(expr_list:REG_EQUIV (const_int 256 [0x100])
(nil)))
Register 355 is recognized as always-equal to the constant 256, and insn 539 is
the insn that originally sets up the equivalence. If the register doesn't get
a hard reg, what ought to happen is that users of reg 355 get replaced by the
constant, and the insn setting the equivalence ought to be deleted. Because
the insn will get deleted anyway, it also ought to be skipped for find_reloads.
To achieve that, reg_equiv_constant(355) should hold the constant, and
reg_equiv_init(355) should point to the above insn. However, what actually
happens in this test case is that reg_equiv_init(355) is NULL. Therefore, the
insn is *not* skipped for find_reloads, which then aborts since it tries to
push an output reload for an always-constant register, which is not supposed to
happen.
Now the register is somewhat special in that it was created by IRA via live
range splitting. The original register was reg 313; and this still has
reg_equiv_init(313) pointing to the above insn. However, reg_equiv_init(355)
is NULL. There is a routine fix_reg_equiv_init in ira.c which appears to be
intended to fix the reg_equiv_init settings of new registers created by live
range splitting. However, this doesn't seem to have worked in this case ...
Unfortunately I'm not really familiar with the live range splitting code; maybe
Vladimir can help with this?