Hi, adjusted patch to make it more bullet-proved and tested it.
2014-05-26 Kai Tietz <kti...@redhat.com> * config/i386/i386.c (ix86_expand_call): Enforce for sibcalls on memory the use of accumulator-register. (ix86_function_ok_for_sibcall): Reject for x86_64 ABI sibling calls for varardic-functions. Regression tested for x86_64-unknown-linux-gnu, x86_64-w64-mingw32, and i686-pc-cygwin. Ok for apply? Regards, Kai Index: i386.c =================================================================== --- i386.c (revision 210936) +++ i386.c (working copy) @@ -5298,6 +5298,12 @@ ix86_function_ok_for_sibcall (tree decl, tree exp) decl_or_type = type; } + /* We need to reject stdarg-function for x86_64 ABI as accumulator + is used as argument. */ + if (TARGET_64BIT && stdarg_p (type) + && ix86_function_type_abi (type) == SYSV_ABI) + return false; + /* Check that the return value locations are the same. Like if we are returning floats on the 80387 register stack, we cannot make a sibcall from a function that doesn't return a float to a @@ -24916,8 +24922,19 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx call ? !sibcall_insn_operand (XEXP (fnaddr, 0), word_mode) : !call_insn_operand (XEXP (fnaddr, 0), word_mode)) { + rtx r; fnaddr = convert_to_mode (word_mode, XEXP (fnaddr, 0), 1); - fnaddr = gen_rtx_MEM (QImode, copy_to_mode_reg (word_mode, fnaddr)); + if (!sibcall) + r = copy_to_mode_reg (word_mode, fnaddr); + else + { + r = gen_rtx_REG (word_mode, AX_REG); + if (! general_operand (fnaddr, VOIDmode)) + fnaddr = force_operand (fnaddr, r); + if (fnaddr != r) + emit_move_insn (r, fnaddr); + } + fnaddr = gen_rtx_MEM (QImode, r); } call = gen_rtx_CALL (VOIDmode, fnaddr, callarg1);