This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/65358] New: parameter passing bug with tail call optimization on arm
- From: "hong.gyu.kim at lge dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Mon, 09 Mar 2015 05:56:02 +0000
- Subject: [Bug target/65358] New: parameter passing bug with tail call optimization on arm
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65358
Bug ID: 65358
Summary: parameter passing bug with tail call optimization on
arm
Product: gcc
Version: 5.0
Status: UNCONFIRMED
Severity: critical
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: hong.gyu.kim at lge dot com
struct pack
{
int fine;
int victim;
int killer;
};
int bar(int a, int b, struct pack p);
int foo(int arg1, int arg2, int arg3, struct pack p)
{
return bar(arg2, arg3, p);
}
When I cross compile the above code with "-O2" option for arm, one variable in
"struct pack" is lost.
The "vitcim" value is overwritten by "killer" value while passing arguments in
"struct pack" from "foo" to "bar".
Initially the arguments are passed this way right after foo invoked.
r0: arg1
r1: arg2
r2: arg3
r3: p.fine
MEM[sp]: p.victim
MEM[sp-4]: p.killer
Parameter setting for bar must be this way right before bar invoked.
r0: arg2
r1: arg3
r2: p.fine
r3: p.victim
MEM[sp]: p.killer
But parameter passing is structured as follows:
(p.victim is overwritten by p.killer)
r0: arg2
r1: arg3
r2: p.fine
r3: p.killer (*)
MEM[sp]: p.killer
The assembly code of "foo" generated is as follows:
foo:
@ args = 16, pretend = 8, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
sub sp, sp, #8
mov r0, r1
str lr, [sp, #-4]!
add ip, sp, #8
(1) ldr lr, [sp, #16]
mov r1, r2
str r3, [sp, #8]
(2) str lr, [sp, #12]
ldr lr, [sp], #4
ldmia ip, {r2, r3}
add sp, sp, #8
b bar
The point is that (1) loads "p.killer", then (2) overwrites "p.victim" value.
Until this point, "p.victim" is never copied anyway, which makes the value
disappear.
This bug is not shown when compiled with "-fno-optimize-sibling-calls".
This bug is shown in gcc-4.9.2 and also in gcc-5.0.0.
I also compiled the same program for x86 and x86_64 and those do not generate
this kind of buggy code. This bug is only shown in arm code.
I found that this bug is detected right after the RTL expand phase. (with
-fdump-rtl-expand)