Hello, I hope that I'm at the right place here. I'm using debian gcc-avr: Package: gcc-avr Version: 1:4.1.0-1 -- System Information: Debian Release: testing/unstable APT prefers testing APT policy: (850, 'testing'), (600, 'unstable'), (1, 'experimental') Architecture: i386 (i686) Shell: /bin/sh linked to /bin/dash Kernel: Linux 2.6.15-1-k7 Locale: LANG=de_AT, LC_CTYPE=de_AT (charmap=ISO-8859-1) Versions of packages gcc-avr depends on: ii binutils-avr 2.16.1-1 Binary utilities that support Atme ii libc6 2.3.6-7 GNU C Library: Shared libraries gcc-avr recommends no packages. -- no debconf information This piece of code gets compiled incorrectly. SIGNAL(SIG_INTERRUPT0) { if (PIND & _BV(PD2)) { low_period=TCNT1; } else { high_period=TCNT1; } } The result is: SIGNAL(SIG_INTERRUPT0) { 294: 1f 92 push r1 296: 0f 92 push r0 298: 0f b6 in r0, 0x3f ; 63 29a: 0f 92 push r0 29c: 11 24 eor r1, r1 29e: 2f 93 push r18 2a0: 8f 93 push r24 2a2: 9f 93 push r25 if (PIND & _BV(PD2)) 2a4: 4a 9b sbis 0x09, 2 ; 9 2a6: 09 c0 rjmp .+18 ; 0x2ba <__vector_1+0x26> { // now H high_period=TCNT1; 2a8: 80 91 84 00 lds r24, 0x0084 2ac: 90 91 85 00 lds r25, 0x0085 2b0: 90 93 0c 01 sts 0x010C, r25 2b4: 80 93 0b 01 sts 0x010B, r24 2b8: 08 c0 rjmp .+16 ; 0x2ca <__vector_1+0x36> } else { low_period=TCNT1; 2ba: 20 91 84 00 lds r18, 0x0084 2be: 30 91 85 00 lds r19, 0x0085 2c2: 30 93 0e 01 sts 0x010E, r19 2c6: 20 93 0d 01 sts 0x010D, r18 2ca: 9f 91 pop r25 2cc: 8f 91 pop r24 2ce: 2f 91 pop r18 2d0: 0f 90 pop r0 2d2: 0f be out 0x3f, r0 ; 63 2d4: 0f 90 pop r0 2d6: 1f 90 pop r1 2d8: 18 95 reti - r0, r1 are pushed/popped, r1 is zeroed. If 0x3f really needs to be saved, it could be done by another register, which has to be used anyway. (or instead of (r18, r19, r24, r25) (r0,r1) should be used.) - r19 is modified, but not saved - this whole construct could be optimized very much better. - -Os, as already used, is much better than without. -O7 or -O2 give the same result as -Os. Please see the attached files for details. Thank you.
Created attachment 11452 [details] The C file
Created attachment 11453 [details] The Makefile
Created attachment 11454 [details] The preprocessor output
Created attachment 11455 [details] The output (dump) file
> - r19 is modified, but not saved Can you please give the exact command line you used to compile bug.i into bug.o?
CFLAGS:=-g -mmcu=$(MCU) -Wall -Wstrict-prototypes -O2 -mcall-prologues -I/usr/avr/include -I/home/flip/cprogs/AVR/include -funroll-loops -save-temps %.s: %.c $(CC) $(CFLAGS) -Os -S $< The .i results from the -save-temps (which I added for reporting this bug) Regards, Phil
> - r19 is modified, but not saved I can confirm this bug for 4.1 and trunk using this line: avr-gcc -c -O1 bug.i -funroll-loops The bug goes away when -funroll-loops is not used. The bug first appeared in july 2005 on head. Works on 3.4.6, 4.0. Is this one related to PR16563?
If I remove the -funroll-loops, will it cause "better" code generation? I.e. only save two registers at function start, and use just these two registers? Can I achieve such an optimization without doing assembly myself? Thank you for your help! Regards, Phil
Testing for bug: - r19 is modified, but not saved avr-gcc -c -O1 bug.i -funroll-loops: - fails with 4.2.0 - succeeds with 4.3-20070525 avr-gcc -c -O1 bug.i: - succeeds with 4.2.0
Fixed for 4.3.0, WONTFIX on the branches.