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

Reply via email to