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

            Bug ID: 118925
           Summary: Comparison of the copy of a volatile register variable
                    instead of the (register) variable
           Product: gcc
           Version: 14.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ul...@t-online.de
  Target Milestone: ---

Created attachment 60522
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=60522&action=edit
example

There is a circular buffer with 2 indices. The indices are modified in a ISR.
The circular buffer is empty if the both indices are equal.

    uint8_t RxBuf[16];
    volatile uint8_t RxHead;
    volatile uint8_t RxTail;

       ...

    while( RxHead == RxTail );  // wait until new char is in buffer (by ISR)


Works as expected as long as at least one index is not bound to a register <
r8.

For example: 
    register volatile uint8_t RxHead asm ("r6");
    register volatile uint8_t RxHead asm ("r7");

In this case:
    while( RxHead == RxTail );

is compiled to the following code:

00000000 <main>:
   0:   96 2d           mov     r25, r6
   2:   87 2d           mov     r24, r7

00000004 <.L2>:
   4:   98 17           cp      r25, r24
   6:   f1 f3           breq    .-4             ; 0x4 <.L2>


The volatile register variable is copied to a temporary register (r25 or r24)
and only the temporary register is compared. If the ISR changes the indices (r6
or r7), this is not recognized.

This only applies to registers < r8. The same compiled with r8, r9 results:

00000000 <main>:
   0:   89 14           cp      r8, r9
   2:   f1 f3           breq    .-4             ; 0x0 <main>


GCC version and build flags:
$ avr-gcc -v
Using built-in specs.
Reading specs from /usr/local/avr/lib/gcc/avr/14.2.0/device-specs/specs-avr2
COLLECT_GCC=avr-gcc
COLLECT_LTO_WRAPPER=/usr/local/avr/libexec/gcc/avr/14.2.0/lto-wrapper
Target: avr
Configured with: ../configure --prefix=/usr/local/avr --target=avr
--enable-languages=c,c++ --disable-nls --disable-libssp --with-dwarf2
Thread model: single
Supported LTO compression algorithms: zlib
gcc version 14.2.0 (GCC)

Compilation:
avr-gcc -Os -fwhole-program -mrelax -Wall -Wextra --save-temps -mmcu=avr25
-DF_CPU=1000000 main.c -o main.elf

Reply via email to