This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/26826] [4.1/4.2 Regression] ICE in reg_or_subregno, at jump.c:2011
- From: "matz at suse dot de" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 25 Mar 2006 21:10:48 -0000
- Subject: [Bug target/26826] [4.1/4.2 Regression] ICE in reg_or_subregno, at jump.c:2011
- References: <bug-26826-10053@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Comment #6 from matz at suse dot de 2006-03-25 21:10 -------
The sequence of what happens is a bit involved, and breaks a very old
invariant in reload.c which doesn't seem to hold anyway since a long
time, as there is already much code handling this non-holding, namely
that subreg's of MEM only happen for paradoxical subregs, except on
WORD_REGISTER_OPERATIONS machines. OTOH there is also other code in reload*.c
which still seem to rely on this invariant (like this asserting code here), or
tries to make sure it's true (e.g. in eliminate_regs_1).
So, what happens is this:
* pseudo 64 doesn't get a hardreg, and we are faced with
(subreg:QI (reg:SI 64)) in some operand
* the first time through the reload loop, reg_equiv_memory_loc[64] is
still zero, hence no elimination is run on it, and no stackslot is created
for it yet.
* first time in calculate_needs_all_insns() it does an eliminate_regs
call on the insn in question. As reg_equiv_memory_loc[64] is not yet
filled in it goes down until eliminate_regs_1((reg:SI 64)), which
then allocates the stack-slot for pseudo 64 in alter_reg. [this already
is strange design, that stackslots are created sort of by accident in
random order by trying to eliminate other regs]
* now reg_equiv_memory_loc[64] _is_ set up to that new stack slot.
But we are still deep down in the calculate_needs_all_insns() activation,
not in the outer reload loop. Hence reg_equiv_mem[64] or
reg_equiv_address[64] are not yet filled (they are normally setup from
reg_equiv_memory_loc[64] just before the whole insn scanning).
* now the insn in question is scanned further, and eventually goes into
find_reloads(), which, before scanning constraints, tries to reload
operand addresses. When it sees a SUBREG in an operand (as here),
it uses find_reloads_toplev on that one.
* find_reloads_toplev tries to handle SUBREGs sensible, i.e. tries to
avoid creating (subreg (mem ...)), but can only do that if either
reg_equiv_address[regno] or reg_equiv_mem[regno] are set up. See above
for why this normally, but not here, is the case.
* So it happily creates the problematic (subreg:QI (mem:SI stackslot))
which is stored into recog_data.operand[i] in find_reloads, so that
further on we see that subreg-mem as operand (for this run in find_reloads).
* Further down the road it checks constraints, which all are fine, but then
comes optional reloads.
* find_reloads tries to be nice to reload inheritance and creates an
optional reload for each MEM operand (or subreg thereof), i.e. also
for this one, so push_reload() is called on it.
* push_reload doesn't expect a SUBREG of MEM which isn't paradoxical,
and has even some gcc_assert to that effect in some of it's conditional
blocks.
* OTOH it also has code to explicitely handle SUBREGs where the inner
reg is not REG_P, but perhaps that is supposed to only handle subregs
of constants, not (subreg(mem)). And it has to expect some
non-paradoxical (subreg(mem)) on WORD_REGISTER_OPERATIONS machines anyway.
If either the stackslots would have been set up already by the time
calculate_needs_all_insns runs, or find_reloads_toplev would also deal
with only reg_equiv_memory_loc being set (which it can't) this problem
wouldn't have occured.
Sooo, the easiest solution for this I believe is that patch which Richard
already mentioned (perhaps attach it here?), which simply also tests
REG_P (SUBREG_REG (in/out)) in both places. The other solution would
be to reinstate the invariant of subreg(mem) never occuring except on
some machines, but that would be much harder to prove correct.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26826