Hello all,
I'm preparing and testing SMS correction/improvements patch and while
testing it on the SPU with the vectorizer testcases I've got an ICE in
the "gcc_assert ( MAX_RECOG_OPERANDS - i)" in function copy_insn_1 in
emit_rtl.c. The call traces back to the loop versionioning called in
modulo-sched.c before the SMSing actually starts. The specific
instruction it tries to copy when it fails is
(insn 32 31 33 4 (parallel [
(set (reg:SI 162)
(div:SI (reg:SI 164)
(reg:SI 156)))
(set (reg:SI 163)
(mod:SI (reg:SI 164)
(reg:SI 156)))
(clobber (scratch:SI))
(clobber (scratch:SI))
(clobber (scratch:SI))
(clobber (scratch:SI))
(clobber (scratch:SI))
(clobber (scratch:SI))
(clobber (scratch:SI))
(clobber (scratch:SI))
(clobber (scratch:SI))
(clobber (reg:SI 130 hbr))
]) 129 {divmodsi4} (insn_list:REG_DEP_TRUE 30
(insn_list:REG_DEP_TRUE 31 (nil)))
(expr_list:REG_DEAD (reg:SI 164)
(expr_list:REG_DEAD (reg:SI 156)
(expr_list:REG_UNUSED (reg:SI 130 hbr)
(expr_list:REG_UNUSED (scratch:SI)
(expr_list:REG_UNUSED (scratch:SI)
(expr_list:REG_UNUSED (scratch:SI)
(expr_list:REG_UNUSED (scratch:SI)
(expr_list:REG_UNUSED (scratch:SI)
(expr_list:REG_UNUSED (scratch:SI)
(expr_list:REG_UNUSED (scratch:SI)
(expr_list:REG_UNUSED (scratch:SI)
(expr_list:REG_UNUSED
(scratch:SI)
(expr_list:REG_UNUSED (reg:SI 163)
(nil)))))))))))))))
The error happens in the first call to copy_insn_1 in the loop below
(copied from emit_copy_of_insn_after from emit_rtl.c):
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) != REG_LABEL)
{
if (GET_CODE (link) == EXPR_LIST)
REG_NOTES (new)
= copy_insn_1 (gen_rtx_EXPR_LIST (REG_NOTE_KIND (link),
XEXP (link, 0),
REG_NOTES (new)));
else
REG_NOTES (new)
= copy_insn_1 (gen_rtx_INSN_LIST (REG_NOTE_KIND (link),
XEXP (link, 0),
REG_NOTES (new)));
}
Tracing the execution of copy_insn_1, it seems that it goes over the
same REG_NOTES many times (it seems to be a quadratic time complexity
algorithm). This causes "copy_insn_n_scratches++" to be executed more
times than there are SCRATCH registers (and even REG_NOTES) leading to
the failure in the assert. There are 9 SCRATCH registers used in the
instruction and MAX_RECOG_OPERANDS is 30 for the SPU.
Since copy_insn_n_scratches is initialized in copy_insn and since we
go over regnotes over and over again, I've modified in the loop
above the two calls to copy_insn_1 with the calls to copy_insn. This
caused the ICEs in the testsuite to disappear.
I wonder if this constitutes a legitimate fix or I'm missing something?
Thanks in advance,
Vladimir