avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] Bug with -flto optimization, omits check for variable


From: Bill Westfield
Subject: Re: [avr-gcc-list] Bug with -flto optimization, omits check for variable if weak/zero symbol is present...
Date: Sun, 8 Jul 2018 01:53:32 -0700

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 <address@hidden> 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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]