http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50074
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #14 from Jakub Jelinek <jakub at gcc dot gnu.org> 2011-11-25 13:08:51 UTC --- (In reply to comment #11) > Created attachment 25858 [details] > Patch to make mem_overlaps_already_clobbered_arg_p return false if no > arguments > were stored on stack > > This patch fixes the sibcall-6.c failure on Epiphany. This patch is certainly correct, please submit it to gcc-patches. That said, this isn't enough. For i?86, it should be probably enough to revert Kyrill's patch and do something like: --- gcc/expr.c.jj 2011-11-21 16:22:02.000000000 +0100 +++ gcc/expr.c 2011-11-25 12:46:40.070831662 +0100 @@ -7452,7 +7452,8 @@ expand_expr_addr_expr_1 (tree exp, rtx t } if (modifier != EXPAND_INITIALIZER - && modifier != EXPAND_CONST_ADDRESS) + && modifier != EXPAND_CONST_ADDRESS + && modifier != EXPAND_SUM) result = force_operand (result, target); return result; } (untested so far, but if it works, is IMHO desirable in any case). Unfortunately we have ia64 which only allows registers in memory addresses and thus we'd miscompile e.g. struct S { long s[4]; }; __attribute__((noinline, noclone)) void bar (long r0, long r1, long r2, long r3, long r4, long r5, long r6, long r7, long r8, long r9, long r10, long r11) { asm volatile (""); } void foo (long r0, long r1, long r2, long r3, long r4, long r5, long r6, long r7, long x, struct S y) { bar (r0, r1, r2, r3, r4, r5, r6, r7, y.s[0], y.s[1], y.s[2], y.s[3]); } BTW, Kyrill's patch didn't deal with arbitrary pseudo plus constant or pseudo plus pseudo. Rejecting all pseudos is way too conservative though, tree-tailcall.c doesn't allow tailcalls if caller has address taken on any of the operands, thus the only case when pseudos point into the arguments area is when the pseudo is initialized in the current get_insns () list to something based on internal argument pointer. I'd say we could just look up (and cache) which pseudos in the current get_insns () list are crtl->args.internal_arg_pointer based and their corresponding offsets from it (if constant, or something that says they are variable).