https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127237

            Bug ID: 127237
           Summary: [avr] IRA bloats code due to LRA
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: gjl at gcc dot gnu.org
  Target Milestone: ---

typedef __UINT32_TYPE__ T;

T and_not (T a, T b)
{
    return a & ~b;
}

In this test case, b is passed in R18:SI and a is passed in R22:SI.
The expected code is that b is COMplemented in place, and the outcome is then
ANDed with a.  That are 8 instructios, and it is what avr-gcc v14 and v15 are
doing:

$ avr-gcc-15 and-not.c -S -Os && cat and-not.s

        com r18
        com r19
        com r20
        com r21
        and r22,r18
        and r23,r19
        and r24,r20
        and r25,r21

With v16 and trunk however, IRA moves stuff around for no reason, adding 14
superfluous instructions and 2 stack slots:

$ avr-gcc-16 and-not.c -S -Os && cat and-not.s

        push r28
        push r29
/* stack size = 2 */
        mov r30,r24
        mov r31,r25
        mov r24,r18
        mov r25,r19
        mov r26,r20
        mov r27,r21
        com r24
        com r25
        com r26
        com r27
        and r24,r22
        and r25,r23
        and r26,r30
        and r27,r31
        mov r22,r24
        mov r23,r25
        mov r24,r26
        mov r25,r27
        pop r29
        pop r28

The obvious change that introduced this was the switch to LRA:  avr-gcc v15
supports -mlra, and with that switch the code from v15 is the same bloat like
from v16 / trunk.

So for some reason, IRA lost capabilities just by enabling LRA instead of
reload.

Reply via email to