Bug 11826 - [ARM] Minor register allocation problem before function return
Summary: [ARM] Minor register allocation problem before function return
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 3.4.0
: P3 enhancement
Target Milestone: 4.4.0
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization, ra
Depends on: 18427
Blocks: 16996
  Show dependency treegraph
 
Reported: 2003-08-06 09:13 UTC by Gábor Lóki
Modified: 2009-03-17 11:19 UTC (History)
2 users (show)

See Also:
Host:
Target: arm-*-elf
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-09-07 17:54:17


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Gábor Lóki 2003-08-06 09:13:52 UTC
For C functions with a return value GCC should store the result of the last
instruction just before returning it in r0 (in order to avoid using unnecessary
register moves).
The new register allocation algorithm doesn't solve this problem either.

--- c example ---
int foo (int a, int b)
{
  if(a+b == 0) return a-b;
  return b-a;
}

--- arm code ---
--- arm-elf-gcc -S -g0 -Os -o reg-alloc.s reg-alloc.c ---
foo:
 cmn r0, r1
 rsb r3, r1, r0
 rsbne r3, r0, r1
 mov r0, r3
 mov pc, lr

--- arm code with new-ra ---
--- arm-elf-gcc -S -g0 -Os -fnew-ra -o reg-alloc.s reg-alloc.c ---
foo:
 mov r3, r0
 cmn r3, r1
 rsb r0, r1, r0
 rsbne r0, r3, r1
 mov pc, lr

--- possible solution ---
foo:
   cmn r0, r1
   rsbeq r0, r1, r0
   rsbne r0, r0, r1
   mov pc, lr
Comment 1 Dara Hazeghi 2003-08-25 00:11:10 UTC
Confirmed with gcc mainline (20030824).
Comment 2 Khem Raj 2005-09-27 03:09:21 UTC
This is fixed in GCC 3.4.4 as well as on mainline. This can be closed.
Comment 3 Andrew Pinski 2005-09-27 13:45:03 UTC
Still happens on the mainline:
        cmn     r0, r1
        rsb     r3, r1, r0
        rsbne   r3, r0, r1
        mov     r0, r3
Comment 4 Alexandre Pereira Nunes 2008-02-08 16:51:52 UTC
I suggest closing this unless reproductible on gcc 4.3.x, since at least vanilla arm-elf-gcc 4.2.2 is correct:

foo:
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        cmn     r1, r0
        rsbeq   r0, r1, r0
        rsbne   r0, r0, r1
        @ lr needed for prologue
        bx      lr
        .size   foo, .-foo
        .ident  "GCC: (GNU) 4.2.2"
Comment 5 Steven Bosscher 2008-11-29 19:28:16 UTC
Can an ARM maintainer please check this bug?  Comment #4 suggests this bug is fixed, but it needs re-checking now that IRA has been merged.
Comment 6 Ramana Radhakrishnan 2009-03-13 12:28:31 UTC
(In reply to comment #5)
> Can an ARM maintainer please check this bug?  Comment #4 suggests this bug is
> fixed, but it needs re-checking now that IRA has been merged.

This is now fixed on mainline even after IRA . This bug can now be closed. 

foo:
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        mov     r3, r0
        cmn     r1, r0
        rsbeq   r0, r1, r0
        rsbne   r0, r3, r1
        bx      lr
        .size   foo, .-foo
        .ident  "GCC: (GNU) 4.4.0 20090312 (experimental)"
Comment 7 Richard Earnshaw 2009-03-17 11:19:12 UTC
(In reply to comment #6)
> foo:
>         mov     r3, r0
>         cmn     r1, r0
>         rsbeq   r0, r1, r0
>         rsbne   r0, r3, r1
>         bx      lr

This appears to be the code generated at -O1 and although the return is fixed, the redundant insn has now moved to the prologue...

Fortunately at -Os and -O2 the output is sensible:

foo:
        cmn     r1, r0
        rsbeq   r0, r1, r0
        rsbne   r0, r0, r1
        bx      lr