avr-gcc -Os: __flash disregarded for some struct array accesses At -Os, avr-gcc generates a plain ld (RAM load) instead of lpm (flash load) for the first field of a const __flash-qualified struct array element, while correctly emitting lpm for the second field of the same element. The struct's first field ends up reading garbage off RAM space instead of the intended flash-resident constant. Reproduced with: - avr-gcc (Gentoo 15.2.1_p20260214 p5) 15.2.1 - avr-gcc 13.2.1 - git revision b6825a7ce698b65657e952e437ab9edd655fe5a5 (2026-07-06) Not reproduced with -O0, -O1, -O2, only -Os. Bug not present in a 2020 build (unknown avr-gcc version). Minimal reproduction #include struct pair { unsigned char data; unsigned char cmd; }; const __flash struct pair table[] = { {0x11, 1}, {0x33, 0}, {0x55,1} }; void write_data(unsigned char d); void write_cmd(unsigned char c); void test(void){     unsigned char i;     for(i=0; i<3; i++){         if(table[i].cmd) write_data(table[i].data); else write_cmd(table[i].data);     } } Build: avr-gcc -Os -mmcu=atmega8 -I/usr/avr/include -S -o test.s test.c Relevant output (-Os): test:     push r28     push r29     ldi r28,lo8(table)     ldi r29,hi8(table) .L4:     movw r30,r28     ld r24,Z+          ; <-- BUG: reads table[i].data from DATA SPACE (SRAM), not flash     lpm r25,Z           ; correct: reads table[i].cmd from flash     cpi r25,lo8(0)     breq .L2     rcall write_data    ; called with garbage r24 (SRAM byte at address `table`), not 0x11/0x33/0x55 .L3:     adiw r28,2     ldi r24,hi8(table+6)     cpi r28,lo8(table+6)     cpc r29,r24     brne .L4     pop r29     pop r28     ret .L2:     rcall write_cmd     rjmp .L3 A single, non-looping access to the same kind of struct correctly uses lpm at every optimization level tested, so this may be specific to the loop/pointer-increment shape above, not __flash struct access in general: struct pair { unsigned char a; unsigned char b; }; const __flash struct pair table[] = { {0x11, 0x22}, {0x33, 0x44} }; unsigned char out; void test(unsigned char i){     out = table[i].a;   // correctly compiles to lpm at -Os } Workaround: replace const __flash with PROGMEM, use pgm_read_* for access.