This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Deadly optimization bug (all gcc versions!)


Am Die, 17 Aug 1999 schrieb Joern Rennecke:
>> After the call to try_combine the instructions are deleted. try_combine is
>> entered with:
>> (gdb) p debug_rtx(i3)
>> 
>> (insn 22 20 24 (set (reg:SI 86)
>>         (lshiftrt:SI (reg:SI 3 r3)
>>             (const_int 1 [0x1]))) 52 {*addsi3_internal1} (insn_list 14 (insn_list 20 (nil)))
>>     (expr_list:REG_DEAD (reg/v:SI 85)
>>         (expr_list:REG_DEAD (reg:SI 87)
>>             (nil))))
>> $134 = void
>> (gdb) p debug_rtx(i2)
>> 
>> (insn 20 17 22 (set (reg:SI 87)
>>         (lshiftrt:SI (reg/v:SI 84)
>>             (const_int 1 [0x1]))) 211 {lshrsi3_no_power} (insn_list 17 (nil))
>>     (expr_list:REG_DEAD (reg/v:SI 84)
>>         (nil)))
>> $135 = void
>> (gdb) p debug_rtx(i1)
>> 
>> (insn 14 11 17 (set (reg/v:SI 85)
>>         (lshiftrt:SI (reg:SI 3 r3)
>>             (const_int 1 [0x1]))) 211 {lshrsi3_no_power} (nil)
>>     (expr_list:REG_DEAD (reg:SI 3 r3)
>>         (nil)))
>
>try_combine assumes that i2 feeds i3, and i1 feeds i2 and/or i3.
>This is clearly not the case here, the the call is in error.
>Look for the cause, probably some bogus LOG_LINKS.

Argh, sorry. I did not backscroll far enough, the correct i3,i2,i1 at the
beginning are:

(gdb) p debug_rtx(i3)

(insn 22 20 24 (set (reg:SI 86)
        (plus:SI (reg/v:SI 85)
            (reg:SI 87))) 52 {*addsi3_internal1} (insn_list 14 (insn_list 20 (nil)))
    (expr_list:REG_DEAD (reg/v:SI 85)
        (expr_list:REG_DEAD (reg:SI 87)
            (nil))))
$181 = void
(gdb) p debug_rtx(i2)

(insn 14 11 17 (set (reg/v:SI 85)
        (lshiftrt:SI (reg:SI 3 r3)
            (const_int 1 [0x1]))) 211 {lshrsi3_no_power} (nil)
    (expr_list:REG_DEAD (reg:SI 3 r3)
        (nil)))
$182 = void
(gdb) p debug_rtx(i1)

(insn 20 17 22 (set (reg:SI 87)
        (lshiftrt:SI (reg/v:SI 84)
            (const_int 1 [0x1]))) 211 {lshrsi3_no_power} (insn_list 17 (nil))
    (expr_list:REG_DEAD (reg/v:SI 84)
        (nil)))
$183 = void

So the feed rules are fulfilled. In the meantime I believe I narrowed it down a
bit to this code around line 1740:

  /* If we already got a failure, don't try to do more.  Otherwise,
     try to substitute in I1 if we have it.  */

  if (i1 && GET_CODE (newpat) != CLOBBER)
    {
      /* Before we can do this substitution, we must redo the test done
         above (see detailed comments there) that ensures  that I1DEST
         isn't mentioned in any SETs in NEWPAT that are field assignments.  */

      if (! combinable_i3pat (NULL_RTX, &newpat, i1dest, NULL_RTX,
                              0, NULL_PTR))
        {
          undo_all ();
          return 0;
        }

      n_occurrences = 0;
      subst_low_cuid = INSN_CUID (i1);
      newpat = subst (newpat, i1dest, i1src, 0, 0);
      undobuf.previous_undos = undobuf.undos;
    }


Before the call to subst newpat/i1dest/i1src look like:

(gdb) p debug_rtx(newpat)

(set (reg:SI 86)
    (plus:SI (lshiftrt:SI (reg/v:SI 84)
            (const_int 1 [0x1]))
        (reg/v:SI 85)))
$184 = void
(gdb) p debug_rtx(i1dest)

(reg/v:SI 85)
$185 = void
(gdb) p debug_rtx(i1src)

(lshiftrt:SI (reg:SI 3 r3)
    (const_int 1 [0x1]))

which looks quite reasonable for newpat (I'm not sure about i1dest/i1src).
But after subst() newpat looks like:

(gdb) p debug_rtx(newpat)

(set (reg:SI 86)
    (lshiftrt:SI (reg:SI 3 r3)
        (const_int 1 [0x1])))

Franz.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]