Attached code file is compiled. Here is the critical passage: inline void taskSignal(void) { unsigned char i; PORTB |= _BV(PB4); PORTB |= _BV(PB5); PORTB |= _BV(PB6); i=0; do { i+=2; } while( i<245 ); i=0; do { i+=3; } while( i<245 ); PORTB &= ~_BV(PB4); i=pos1; do { i+=1; } while( i<245 ); PORTB &= ~_BV(PB5); PORTB &= ~_BV(PB6); } When compiling without optimization I get: do { i+=2; 41e: 89 81 ldd r24, Y+1 ; 0x01 420: 8e 5f subi r24, 0xFE ; 254 422: 89 83 std Y+1, r24 ; 0x01 } 424: 89 81 ldd r24, Y+1 ; 0x01 426: 85 3f cpi r24, 0xF5 ; 245 428: 08 f4 brcc .+2 ; 0x42c <taskSignal+0x42> 42a: f9 cf rjmp .-14 ; 0x41e <taskSignal+0x34> while( i<245 ); But using -Os results in the following code: 262: 80 e0 ldi r24, 0x00 ; 0 do { i+=2; 264: 8a 5f subi r24, 0xFA ; 250 } 266: 85 3f cpi r24, 0xF5 ; 245 268: e8 f3 brcs .-6 ; 0x264 <taskSignal+0x8> while( i<245 ); Please note how the substraction of -2 is optimized in something other. The compiler said: avr-gcc (GCC) 3.4.6 (Gentoo 3.4.6, ssp-3.4.5-1.0, pie-8.7.9) Copyright (C) 2006 Free Software Foundation, Inc. The line calling it was: avr-gcc -c -mmcu=attiny26 -I. -g -DF_CPU=8000000UL -Os -Wall -Wstrict-prototypes -Wa,-adhlns=tester.lst -MD -MP -MF .dep/tester.o.d tester.c -o tester.o
Created attachment 12150 [details] source code which is compiled strangely.
264: 8a 5f subi r24, 0xFA ; 250 That looks fine for me since it is r24 = r24 - -2.
The AVR does not have an Add Immediate instruction (addi), so this is normally done using sbi with a negative number as Andrew correctly points out. In Ralf's unoptimized output, it correctly shows a -2 (0xFE): 41e: 89 81 ldd r24, Y+1 ; 0x01 420: 8e 5f subi r24, 0xFE ; 254 The optimized output shows a -6 (0xFA) 264: 8a 5f subi r24, 0xFA ; 250 Why is this? Well, the optimizer aggressively optimizes loops that do nothing, like the code is here: i=0; do { i+=2; } while( i<245 ); Note that you only have 'i' declared as unsigned char. The first FAQ entry in the avr-libc user manual talks about using the keyword 'volatile': http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_volatile If you define 'i' as volatile unsigned char, then the optimizer will not agressively optimize your "do-nothing" loop. In fact, if you are trying to achieve a delay using a "do-nothing" loop, then you are strongly suggested to use the <util/delay.h> header that comes with avr-libc, which are "busy-wait delay loops": <http://www.nongnu.org/avr-libc/user-manual/group__util__delay.html> GCC Bugmasters: Please close this bug as invalid. Eric Weddington
This is just unrolling/removing empty loops so invalid.
Wow, you mean that unrolling the loop three times but not removing it is the right behaviour? Anyway, 4.1.1 seems to do it right. It's removing the whole loop as expected. delay.h is working.