Bug 27593 - [4.1/4.2 Regression][avr] bad code generation with -funroll-loops
Summary: [4.1/4.2 Regression][avr] bad code generation with -funroll-loops
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.1.0
: P3 normal
Target Milestone: 4.3.0
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks:
 
Reported: 2006-05-13 20:08 UTC by philipp
Modified: 2008-03-14 16:41 UTC (History)
3 users (show)

See Also:
Host: i486-linux-gnu
Target: avr-*-*
Build: i486-linux-gnu
Known to work: 3.4.6
Known to fail: 4.1.0 4.2.0
Last reconfirmed: 2007-04-09 23:31:41


Attachments
The C file (329 bytes, text/x-csrc)
2006-05-13 20:09 UTC, philipp
Details
The Makefile (363 bytes, application/octet-stream)
2006-05-13 20:09 UTC, philipp
Details
The preprocessor output (2.18 KB, application/octet-stream)
2006-05-13 20:10 UTC, philipp
Details
The output (dump) file (1.40 KB, application/octet-stream)
2006-05-13 20:11 UTC, philipp
Details

Note You need to log in before you can comment on or make changes to this bug.
Description philipp 2006-05-13 20:08:54 UTC
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.
Comment 1 philipp 2006-05-13 20:09:30 UTC
Created attachment 11452 [details]
The C file
Comment 2 philipp 2006-05-13 20:09:54 UTC
Created attachment 11453 [details]
The Makefile
Comment 3 philipp 2006-05-13 20:10:15 UTC
Created attachment 11454 [details]
The preprocessor output
Comment 4 philipp 2006-05-13 20:11:01 UTC
Created attachment 11455 [details]
The output (dump) file
Comment 5 berndtrog 2006-05-14 12:39:27 UTC
> - r19 is modified, but not saved

Can you please give the exact command line you used to compile bug.i into bug.o?
Comment 6 philipp 2006-05-15 05:17:53 UTC
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
Comment 7 berndtrog 2006-05-15 20:19:04 UTC
> - 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?
Comment 8 philipp 2006-05-16 08:20:10 UTC
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
Comment 9 Eric Weddington 2007-05-30 22:40:00 UTC
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
Comment 10 Richard Biener 2008-03-14 16:41:34 UTC
Fixed for 4.3.0, WONTFIX on the branches.