https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115817
Bug ID: 115817 Summary: [AVR] Suboptimal code for zeroing SRAM byte from ISR Product: gcc Version: 14.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: dimich.dmb at gmail dot com Target Milestone: --- There are two almost identical ISRs, the difference is only an immediate value to be stored in SRAM. ``` static volatile unsigned char flag; __attribute__ ((__signal__,__used__, __externally_visible__)) void __vector_set_one(void) { flag = 1; } __attribute__ ((__signal__,__used__, __externally_visible__)) void __vector_set_zero(void) { flag = 0; } ``` (The real code is reduced to this MRE to avoid ISR macro from avr-libc header) First function compiles to the following code: 0000000c <__vector_set_zero>: c: 1f 92 push r1 e: 1f b6 in r1, 0x3f ; 63 10: 1f 92 push r1 12: 11 24 eor r1, r1 14: 10 92 00 00 sts 0x0000, r1 ; 0x800000 <__SREG__+0x7fffc1> 18: 1f 90 pop r1 1a: 1f be out 0x3f, r1 ; 63 1c: 1f 90 pop r1 1e: 18 95 reti which looks overcomplicated comparing to the first one: 00000000 <__vector_set_one>: 0: 8f 93 push r24 2: 81 e0 ldi r24, 0x01 ; 1 4: 80 93 00 00 sts 0x0000, r24 ; 0x800000 <__SREG__+0x7fffc1> 8: 8f 91 pop r24 a: 18 95 reti For other non-zero values the code is the same as for `__vector_set_one` except the value itself. The same difference is observed in final ELF binary, regardless of whether compiled and linked with or without `-flto`. Preprocessed file: ``` # 0 "example.c" # 0 "<built-in>" # 0 "<command-line>" # 1 "example.c" static volatile unsigned char flag; __attribute__ ((__signal__,__used__, __externally_visible__)) void __vector_set_one(void) { flag = 1; } __attribute__ ((__signal__,__used__, __externally_visible__)) void __vector_set_zero(void) { flag = 0; } ``` GCC version and build flags: $ avr-gcc -v Using built-in specs. Reading specs from /usr/lib/gcc/avr/14.1.0/device-specs/specs-avr2 COLLECT_GCC=avr-gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/avr/14.1.0/lto-wrapper Target: avr Configured with: /build/avr-gcc/src/gcc-14.1.0/configure --disable-install-libiberty --disable-libssp --disable-libstdcxx-pch --disable-libunwind-exceptions --disable-linker-build-id --disable-nls --disable-werror --disable-__cxa_atexit --enable-checking=release --enable-clocale=gnu --enable-gnu-unique-object --enable-gold --enable-languages=c,c++ --enable-ld=default --enable-lto --enable-plugin --enable-shared --infodir=/usr/share/info --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --prefix=/usr --target=avr --with-as=/usr/bin/avr-as --with-gnu-as --with-gnu-ld --with-ld=/usr/bin/avr-ld --with-plugin-ld=ld.gold --with-system-zlib --with-isl --enable-gnu-indirect-function Thread model: single Supported LTO compression algorithms: zlib zstd gcc version 14.1.0 (GCC) System: Arch Linux, x86_64 GNU/Linux Compilation: $ avr-gcc -Wall -pedantic -Os -mmcu=attiny13a --save-temps -c -o example.o example.c Expected code: __vector_set_zero: push r24 ldi r24, 0x00 sts flag, r24 pop r24 reti