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

Reply via email to