[Bug rtl-optimization/88253] New: Inlining of function incorrectly deletes volatile register access when using XOR in avr-gcc

westfw at westfw dot info gcc-bugzilla@gcc.gnu.org
Thu Nov 29 00:04:00 GMT 2018


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

            Bug ID: 88253
           Summary: Inlining of function incorrectly deletes volatile
                    register access when using XOR in avr-gcc
           Product: gcc
           Version: 5.4.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: westfw at westfw dot info
  Target Milestone: ---

Created attachment 45116
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45116&action=edit
.i pre-processed file from --keep-temps

Using avr-gcc (AVR_8_bit_GNU_Toolchain_3.6.1_495) 5.4.0
(bug also occurs in avr-gcc 4.9 and 8.1; does NOT occur in 4.8.1)

A rather trivial C program:

#include <avr/io.h>
uint16_t aRead() {
    uint8_t h;
    uint8_t l;
    l = ADCL;
    h = ADCH;
    return (h<<8) | l;
}

int main() {
    volatile uint8_t x;
    x = aRead()^42;
}

only reads ADCL when aRead() is inlined from main; the read of (volatile) ADCH
is apparently removed by an optimization step, which breaks things because that
read has side-effects at the hardware level.

00000000 <main>:
   0:   cf 93           push    r28
   2:   df 93           push    r29
   4:   1f 92           push    r1
   6:   cd b7           in      r28, 0x3d       ; 61
   8:   de b7           in      r29, 0x3e       ; 62
   a:   80 91 78 00     lds     r24, 0x0078     ; 0x800078 <__SREG__+0x800039>
   e:   9a e2           ldi     r25, 0x2A       ; 42
  10:   89 27           eor     r24, r25
  12:   89 83           std     Y+1, r24        ; 0x01

This seems to happen during or slightly before the .combine pass of
optimization; the ud_dce output dump shows both volatile accesses, and the
combine has only one.   Does not happen using inclusive-OR, or a plain store.
(yes, I know that the value of ADCH that is read is never actually used.  But
it's volatile, and has side effects, and should be read.)

General compiler command: "avr-gcc -O3 -g adctest.i"
Seems to occur regardless of the reason for inlining - happens with "-Os -fto"
or with -Os and the always_inline attribute specified.

Some discussion at
https://www.avrfreaks.net/forum/avr-gcc-optimization-xor-incorrectly-eliminates-volatile-access


More information about the Gcc-bugs mailing list