http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60486

            Bug ID: 60486
           Summary: [avr] missed optimization on detecting zero flag set
           Product: gcc
           Version: 4.8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: other
          Assignee: unassigned at gcc dot gnu.org
          Reporter: darryl.piper at gmail dot com

detection of a variable being decremented to reach zero missed optimization.

int main(uint16_t, uint16_t );

int main(uint16_t x, uint16_t y) {

  uint16_t z = x;

  while (x > y) {
    if ( --z == 0 ) return 1;
    x++;
  }

  return 0;
}


produces with gcc 4.8.0 and 4.8.1  and I expect 4.8.2 as well.
compiled with -Os

the code at 0x82 to 0x8a  uses a compare against zero, when the subi and sbc,
leave the zero flag set on a atmega8.


  7a:    9c 01           movw    r18, r24

  7c:    68 17           cp    r22, r24
  7e:    79 07           cpc    r23, r25
  80:    38 f4           brcc    .+14         ; 0x90 <main+0x16>

  82:    21 50           subi    r18, 0x01    ; 1
  84:    31 09           sbc    r19, r1
  86:    21 15           cp    r18, r1
  88:    31 05           cpc    r19, r1
  8a:    29 f0           breq    .+10         ; 0x96 <main+0x1c>

  8c:    01 96           adiw    r24, 0x01    ; 1
  8e:    f6 cf           rjmp    .-20         ; 0x7c <main+0x2>


  90:    80 e0           ldi    r24, 0x00    ; 0
  92:    90 e0           ldi    r25, 0x00    ; 0
  94:    08 95           ret

  96:    81 e0           ldi    r24, 0x01    ; 1
  98:    90 e0           ldi    r25, 0x00    ; 0
  9a:    08 95           ret



in gcc/config/avr/avr.md the code for (define_insn "add<mode>3" no longer says
it alters the zero of negative flag which the 4.7.2 branch did depending on
which choice of add & adc or sub & sbc choice it used.

Reply via email to