Bug with -flto optimization, omits check for variable if weak/zero symbol is present...

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Bug with -flto optimization, omits check for variable if weak/zero symbol is present...

Bill Westfield
Discovered on Arduino (4.9.2-atmel3.5.4) ( http://forum.arduino.cc/index.php?topic=556674.0 )
So I have this pretty trivial avr-gcc program:

#include <avr/io.h>

void serialEvent() __attribute__((weak));
void loop();

void serialEventRun(void)
{
#ifndef OMITBUG
  if (serialEvent) serialEvent();
#endif
}

int main() {
    for (;;) {
    loop();
    if (serialEventRun) serialEventRun();
    }
}

int nnn = 1;

void loop()
{
  if (nnn <= 3) {
    char rrr = 0;
    while ( !rrr ) {
      if (PORTB)
        rrr = (PORTB == 'c' );
    }
    PORTB |= 1 << 5;
    nnn++;
  } else while (1);
}

If compile with "avr-gcc -g -Os -flto -mmcu=atmega328p bug.c -o bug.elf" it will produce code that omits the test for (nnn <= 3)
Turning off -flto, or adding -DOMITBUG to the compile line (removing the call to the non-existent serialEvent() function) results in correct code.

Discovered on Arduino (4.9.2-atmel3.5.4) ( http://forum.arduino.cc/index.php?topic=556674.0 )

Also fails with avr-gcc (AVR_8_bit_GNU_Toolchain_3.6.1_496) 5.4.0 and avr-gcc (AVR_8_bit_GNU_Toolchain_3.6.1_1750) 5.4.0
With avr-gcc 8.1, it produce an additional error that may or may not be relevant:

C:\Users\billw\Documents\src>\bin\avr-gcc-8.1.0-x86-mingw\bin\avr-gcc -g -Os -flto -mmcu=atmega328p bug.c -o bug.elf
C:\Users\billw\AppData\Local\Temp\ccE52smMdebugobjtem: file not recognized: File truncated
collect2.exe: error: ld returned 1 exit status
lto-wrapper.exe: fatal error: \bin\avr-gcc-8.1.0-x86-mingw\bin\avr-gcc returned 1 exit status
compilation terminated.
c:/bin/avr-gcc-8.1.0-x86-mingw/bin/../lib/gcc/avr/8.1.0/../../../../avr/bin/ld.exe: error: lto-wrapper failed
collect2.exe: error: ld returned 1 exit status

(8.1 files in ld even with -DOMITBUG, though slightly differenty.  It works without -flto)

Um.  Wild guess:  The   if (serialEvent) serialEvent(); line generates slightly odd code, including a call to an absolute address of 0x0.
Is there something in link that uses a 0x0 address as an "end of list" indicator?
  ba:   20 97           sbiw    r28, 0x00       ; 0
  bc:   71 f3           breq    .-36            ; 0x9a <main+0x4>
  be:   0e 94 00 00     call    0       ; 0x0 <__vectors>


-save-temp data attached for both working and fail cases.


_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list

gcc-lto-bug.zip (45K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Bug with -flto optimization, omits check for variable if weak/zero symbol is present...

Bill Westfield
Someone recently suggested (on the linked Arduino conversation) that this could be due to the "undefined" nature of infinite loops?
Indeed, putting an volatile access or replacing the final "while(1);" loop with an abort() causes the symptom to go away.
Any of the OMITBUGx defines will make it work.

#include <avr/io.h>
#include <stdlib.h>

void serialEvent() __attribute__((weak));
void loop();

void serialEventRun(void)
{
#ifndef OMITBUG
    if (serialEvent) serialEvent();
#endif
}

#ifdef OMITBUG2
void serialEvent() {
}
#endif

int main() {
    for (;;) {
    loop();
    if (serialEventRun) serialEventRun();
    }
}

int nnn = 1;

void loop()
{
    if (nnn <= 3) {
    char rrr = 0;
    while ( !rrr ) {
        if (PORTB)
        rrr = (PORTB == 'c' );
    }
    PORTB |= 1 << 5;
    nnn++;
    } else
#ifdef OMITBUG4
    abort();
#else
    while (1)
#ifndef OMITBUG3
        ;
#else
    PORTB = 1;
#endif
#endif
}



On Fri, Jul 6, 2018 at 6:10 PM, Bill Westfield <[hidden email]> wrote:
Discovered on Arduino (4.9.2-atmel3.5.4) ( http://forum.arduino.cc/index.php?topic=556674.0 )
So I have this pretty trivial avr-gcc program:

#include <avr/io.h>

void serialEvent() __attribute__((weak));
void loop();

void serialEventRun(void)
{
#ifndef OMITBUG
  if (serialEvent) serialEvent();
#endif
}

int main() {
    for (;;) {
    loop();
    if (serialEventRun) serialEventRun();
    }
}

int nnn = 1;

void loop()
{
  if (nnn <= 3) {
    char rrr = 0;
    while ( !rrr ) {
      if (PORTB)
        rrr = (PORTB == 'c' );
    }
    PORTB |= 1 << 5;
    nnn++;
  } else while (1);
}

If compile with "avr-gcc -g -Os -flto -mmcu=atmega328p bug.c -o bug.elf" it will produce code that omits the test for (nnn <= 3)
Turning off -flto, or adding -DOMITBUG to the compile line (removing the call to the non-existent serialEvent() function) results in correct code.

Discovered on Arduino (4.9.2-atmel3.5.4) ( http://forum.arduino.cc/index.php?topic=556674.0 )

Also fails with avr-gcc (AVR_8_bit_GNU_Toolchain_3.6.1_496) 5.4.0 and avr-gcc (AVR_8_bit_GNU_Toolchain_3.6.1_1750) 5.4.0
With avr-gcc 8.1, it produce an additional error that may or may not be relevant:

C:\Users\billw\Documents\src>\bin\avr-gcc-8.1.0-x86-mingw\bin\avr-gcc -g -Os -flto -mmcu=atmega328p bug.c -o bug.elf
C:\Users\billw\AppData\Local\Temp\ccE52smMdebugobjtem: file not recognized: File truncated
collect2.exe: error: ld returned 1 exit status
lto-wrapper.exe: fatal error: \bin\avr-gcc-8.1.0-x86-mingw\bin\avr-gcc returned 1 exit status
compilation terminated.
c:/bin/avr-gcc-8.1.0-x86-mingw/bin/../lib/gcc/avr/8.1.0/../../../../avr/bin/ld.exe: error: lto-wrapper failed
collect2.exe: error: ld returned 1 exit status

(8.1 files in ld even with -DOMITBUG, though slightly differenty.  It works without -flto)

Um.  Wild guess:  The   if (serialEvent) serialEvent(); line generates slightly odd code, including a call to an absolute address of 0x0.
Is there something in link that uses a 0x0 address as an "end of list" indicator?
  ba:   20 97           sbiw    r28, 0x00       ; 0
  bc:   71 f3           breq    .-36            ; 0x9a <main+0x4>
  be:   0e 94 00 00     call    0       ; 0x0 <__vectors>


-save-temp data attached for both working and fail cases.



_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Reply | Threaded
Open this post in threaded view
|

Re: Bug with -flto optimization, omits check for variable if weak/zero symbol is present...

Senthil Kumar Selvaraj-2
In reply to this post by Bill Westfield
j
Bill Westfield writes:

> Discovered on Arduino (4.9.2-atmel3.5.4) (
> http://forum.arduino.cc/index.php?topic=556674.0 )
> So I have this pretty trivial avr-gcc program:
>
> #include <avr/io.h>
>
> void serialEvent() __attribute__((weak));
> void loop();
>
> void serialEventRun(void)
> {
> #ifndef OMITBUG
>   if (serialEvent) serialEvent();
> #endif
> }
>
> int main() {
>     for (;;) {
>     loop();
>     if (serialEventRun) serialEventRun();
>     }
> }
>
> int nnn = 1;
>
> void loop()
> {
>   if (nnn <= 3) {
>     char rrr = 0;
>     while ( !rrr ) {
>       if (PORTB)
>         rrr = (PORTB == 'c' );
>     }
>     PORTB |= 1 << 5;
>     nnn++;
>   } else while (1);
> }
>
> If compile with "avr-gcc -g -Os -flto -mmcu=atmega328p bug.c -o bug.elf" it
> will produce code that omits the test for (nnn <= 3)
> Turning off -flto, or adding -DOMITBUG to the compile line (removing the
> call to the non-existent serialEvent() function) results in correct code.

Can repro this on atmel3.6.1 and gcc-5-branch as well with just
-fwhole-program. Bug goes away on gcc-6-branch and trunk [1]. Will try
to isolate fix and see if it can be backported.

[1] http://avr-gcc.senthilthecoder.com/#g:!((g:!((g:!((h:codeEditor,i:(j:1,options:(colouriseAsm:'0',compileOnChange:'0'),source:'%23include+%3Cavr/io.h%3E%0A%0Avoid+serialEvent()+__attribute__((weak))%3B%0Avoid+loop()%3B%0A%0Avoid+serialEventRun(void)%0A%7B%0A%23ifndef+OMITBUG%0A++if+(serialEvent)+serialEvent()%3B%0A%23endif%0A%7D%0A%0Aint+main()+%7B%0A++++for+(%3B%3B)+%7B%0A%09loop()%3B%0A%09if+(serialEventRun)+serialEventRun()%3B%0A++++%7D%0A%7D%0A%0Aint+nnn+%3D+1%3B%0A%0Avoid+loop()%0A%7B%0A++if+(nnn+%3C%3D+3)+%7B%0A++++char+rrr+%3D+0%3B%0A++++while+(+!!rrr+)+%7B%0A++++++if+(PORTB)%0A++++++++rrr+%3D+(PORTB+%3D%3D+!'c!'+)%3B%0A++++%7D%0A++++PORTB+%7C%3D+1+%3C%3C+5%3B%0A++++nnn%2B%2B%3B%0A++%7D+else+while+(1)%3B%0A%7D%0A'),l:'5',n:'1',o:'C+source+%231',t:'0')),k:33.333333333333336,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:trunk,filters:(b:'0',commentOnly:'0',intel:'0'),options:'-Os+-mmcu%3Datmega328p+-fwhole-program+-v'),l:'5',n:'0',o:'%231+with+trunk',t:'0')),k:33.333333333333336,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:output,i:(compiler:1,editor:1),l:'5',n:'0',o:'%231+with+trunk',t:'0')),k:33.33333333333333,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4

Regards
Senthil

>
> Discovered on Arduino (4.9.2-atmel3.5.4) (
> http://forum.arduino.cc/index.php?topic=556674.0 )
>
> Also fails with avr-gcc (AVR_8_bit_GNU_Toolchain_3.6.1_496) 5.4.0 and
> avr-gcc (AVR_8_bit_GNU_Toolchain_3.6.1_1750) 5.4.0
> With avr-gcc 8.1, it produce an additional error that may or may not be
> relevant:
>
> C:\Users\billw\Documents\src>\bin\avr-gcc-8.1.0-x86-mingw\bin\avr-gcc -g
> -Os -flto -mmcu=atmega328p bug.c -o bug.elf
> C:\Users\billw\AppData\Local\Temp\ccE52smMdebugobjtem: file not recognized:
> File truncated
> collect2.exe: error: ld returned 1 exit status
> lto-wrapper.exe: fatal error: \bin\avr-gcc-8.1.0-x86-mingw\bin\avr-gcc
> returned 1 exit status
> compilation terminated.
> c:/bin/avr-gcc-8.1.0-x86-mingw/bin/../lib/gcc/avr/8.1.0/../../../../avr/bin/ld.exe:
> error: lto-wrapper failed
> collect2.exe: error: ld returned 1 exit status
>
> (8.1 files in ld even with -DOMITBUG, though slightly differenty.  It works
> without -flto)
>
> Um.  Wild guess:  The   if (serialEvent) serialEvent(); line generates
> slightly odd code, including a call to an absolute address of 0x0.
> Is there something in link that uses a 0x0 address as an "end of list"
> indicator?
>   ba:   20 97           sbiw    r28, 0x00       ; 0
>   bc:   71 f3           breq    .-36            ; 0x9a <main+0x4>
>   be:   0e 94 00 00     call    0       ; 0x0 <__vectors>
>
>
> -save-temp data attached for both working and fail cases.
> _______________________________________________
> AVR-GCC-list mailing list
> [hidden email]
> https://lists.nongnu.org/mailman/listinfo/avr-gcc-list

_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list