Index: config/i386/i386-protos.h =================================================================== --- config/i386/i386-protos.h (revision 189280) +++ config/i386/i386-protos.h (working copy) @@ -290,7 +290,6 @@ extern void x86_elf_aligned_common (FILE *, const extern void ix86_fp_comparison_codes (enum rtx_code code, enum rtx_code *, enum rtx_code *, enum rtx_code *); extern enum rtx_code ix86_fp_compare_code_to_integer (enum rtx_code); -extern rtx construct_plt_address (rtx); #endif extern int asm_preferred_eh_data_format (int, int); Index: config/i386/i386.c =================================================================== --- config/i386/i386.c (revision 189280) +++ config/i386/i386.c (working copy) @@ -23090,16 +23090,17 @@ ix86_expand_strlen (rtx out, rtx src, rtx eoschar, /* For given symbol (function) construct code to compute address of it's PLT entry in large x86-64 PIC model. */ -rtx -construct_plt_address (rtx symbol) +static rtx +construct_plt_address (rtx symbol, rtx tmp) { - rtx tmp, unspec; + rtx unspec; gcc_assert (GET_CODE (symbol) == SYMBOL_REF); gcc_assert (ix86_cmodel == CM_LARGE_PIC); gcc_assert (Pmode == DImode); - tmp = gen_reg_rtx (Pmode); + if (!tmp) + tmp = gen_reg_rtx (Pmode); unspec = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol), UNSPEC_PLTOFF); emit_move_insn (tmp, gen_rtx_CONST (Pmode, unspec)); @@ -23155,7 +23156,8 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx call && MEM_P (fnaddr) && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF && !local_symbolic_operand (XEXP (fnaddr, 0), VOIDmode)) - fnaddr = gen_rtx_MEM (QImode, construct_plt_address (XEXP (fnaddr, 0))); + fnaddr = gen_rtx_MEM (QImode, + construct_plt_address (XEXP (fnaddr, 0), NULL_RTX)); else if (sibcall ? !sibcall_insn_operand (XEXP (fnaddr, 0), word_mode) : !call_insn_operand (XEXP (fnaddr, 0), word_mode)) @@ -33057,6 +33059,10 @@ x86_output_mi_thunk (FILE *file, emit_jump_insn (gen_indirect_jump (fnaddr)); else { + if (ix86_cmodel == CM_LARGE_PIC + && GET_CODE (fnaddr) == SYMBOL_REF) + fnaddr = construct_plt_address (fnaddr, + gen_rtx_REG (Pmode, tmp_regno)); if (!sibcall_insn_operand (fnaddr, word_mode)) { tmp = gen_rtx_REG (word_mode, tmp_regno);