In the following code, the tail call in g() is compiled incorrectly on ARM with -O2 or higher (and -fno-inline):
#include <stdio.h> struct s { int x, y, z; }; int f(int a, int b, int c, struct s d, int e) { printf("%d %d %d\n", d.x, d.y, d.z); return 0; } int g(int a, int b, int c, int d, struct s e, int h) { return f(a, b, c, e, h); } int main(void) { f(0, 0, 0, (struct s){ 42, 69, 105 }, 7); g(0, 0, 0, 0, (struct s){ 42, 69, 105 }, 7); return 0; } With -O1 and lower, the result is correct: 42 69 105 42 69 105 With -O2 and higher, it prints: 42 69 105 69 69 7 Inspecting the output of gcc -O3 -fno-inline -S shows that gcc is shifting the arguments on the stack downwards for the tail call. However, it starts at the top, rather than at the bottom. So it writes over two arguments (e.z and e.x) before loading them. This has been broken since 4.1.1 (possibly earlier), and is still broken in 4.2.2. -- Summary: Incorrect code for tail calls with a structure as 4th argument Product: gcc Version: 4.2.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: narge-gcc at derrin dot id dot au GCC target triplet: arm-elf http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34109