http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49519
--- Comment #16 from Yukhin Kirill <kirill.yukhin at intel dot com> 2011-07-06 10:35:03 UTC --- Yes. This is because expander prepares arguments like this: ... (insn 6 5 7 2 (parallel [ (set (reg:SI 64) (plus:SI (reg/f:SI 53 virtual-incoming-args) (const_int 4 [0x4]))) (clobber (reg:CC 17 flags)) ]) 2.cc:103 -1 (nil)) (insn 7 6 8 2 (set (reg:SI 65) (mem/c:SI (plus:SI (reg:SI 64) (const_int 12 [0xc])) [0 MEM[(int &)&t + 12]+0 S4 A32])) 2.cc:103 -1 (nil)) (insn 8 7 9 2 (set (mem:SI (plus:SI (reg/f:SI 53 virtual-incoming-args) (const_int 12 [0xc])) [0 S4 A32]) (reg:SI 65)) 2.cc:103 -1 (nil)) ... So, calls.c/mem_overlaps_already_clobbered_arg_p unable to determine, that data come from stack, so it returns true and enables tailcall.