https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90706
Bug ID: 90706 Summary: Useless code generated for stack / register operations on AVR Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: bseifert at gmx dot at Target Milestone: --- given the following function: unsigned char check(float x) { return (0.0 < x); } in avr-gcc 8.3.0 the following code is generated: 00000098 <_Z5checkf>: 98: cf 93 push r28 9a: c1 e0 ldi r28, 0x01 ; 1 9c: 20 e0 ldi r18, 0x00 ; 0 9e: 30 e0 ldi r19, 0x00 ; 0 a0: a9 01 movw r20, r18 a2: 0e 94 a8 00 call 0x150 ; 0x150 <__gesf2> a6: 18 16 cp r1, r24 a8: 0c f0 brlt .+2 ; 0xac <_Z5checkf+0x14> aa: c0 e0 ldi r28, 0x00 ; 0 ac: 8c 2f mov r24, r28 ae: cf 91 pop r28 b0: 08 95 ret I don't see any room for improvements here. avr-gcc 9.1.0 compiles to the following. I've marked the lines that don't make sense to me. 00000098 <_Z5checkf>: 98: cf 93 push r28 9a: df 93 push r29 * 9c: 00 d0 rcall .+0 ; 0x9e <_Z5checkf+0x6> * 9e: 00 d0 rcall .+0 ; 0xa0 <_Z5checkf+0x8> * a0: 0f 92 push r0 * a2: cd b7 in r28, 0x3d ; 61 * a4: de b7 in r29, 0x3e ; 62 a6: 21 e0 ldi r18, 0x01 ; 1 a8: 2d 83 std Y+5, r18 ; 0x05 aa: 20 e0 ldi r18, 0x00 ; 0 ac: 30 e0 ldi r19, 0x00 ; 0 ae: a9 01 movw r20, r18 * b0: 69 83 std Y+1, r22 ; 0x01 * b2: 7a 83 std Y+2, r23 ; 0x02 * b4: 8b 83 std Y+3, r24 ; 0x03 * b6: 9c 83 std Y+4, r25 ; 0x04 * b8: 69 81 ldd r22, Y+1 ; 0x01 * ba: 7a 81 ldd r23, Y+2 ; 0x02 * bc: 8b 81 ldd r24, Y+3 ; 0x03 * be: 9c 81 ldd r25, Y+4 ; 0x04 c0: 0e 94 dc 00 call 0x1b8 ; 0x1b8 <__gesf2> c4: 18 16 cp r1, r24 c6: 0c f0 brlt .+2 ; 0xca <_Z5checkf+0x32> c8: 1d 82 std Y+5, r1 ; 0x05 ca: 8d 81 ldd r24, Y+5 ; 0x05 cc: 0f 90 pop r0 ce: 0f 90 pop r0 d0: 0f 90 pop r0 d2: 0f 90 pop r0 d4: 0f 90 pop r0 * d6: df 91 pop r29 * d8: cf 91 pop r28 da: 08 95 ret The value is put to Y+1 to Y+4 and then immediately read back. why? pushing r0 does not make sense at all since it is by definition a temporary register that can freely be modified. Maybe it's just pushed to make room for the stack operations? compilation: "D:\AVR\Toolchain\9.1.0\bin\avr-g++.exe" -funsigned-char -funsigned-bitfields -DNDEBUG -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.272\include" -Os -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -mmcu=atmega644 -c -MD -MP -MF "main.d" -MT"main.d" -MT"main.o" -o "main.o" ".././main.cpp" linker: "D:\AVR\Toolchain\9.1.0\bin\avr-g++.exe" -o BugTest.elf main.o -Wl,-Map="BugTest.map" -Wl,--start-group -Wl,-lm -Wl,--end-group -Wl,--gc-sections -mmcu=atmega644