Hello! We have to pass word_mode (DImode for x86_64 target) call operand to ix86_output_call_insn, otherwise invalid DWORD_PTR prefixed address is generated in x32 case.
2016-05-12 Uros Bizjak <ubiz...@gmail.com> * config/i386/i386.md (*call_got_x32): Change operand 0 to DImode before it is passed to ix86_output_call_operand. (*call_value_got_x32): Ditto for operand 1. Patch was bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. Committed to mainline SVN. Uros.
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 9bd19ab..f6bb69b 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -11934,7 +11934,10 @@ (match_operand:SI 0 "GOT_memory_operand" "Bg"))) (match_operand 1))] "TARGET_X32" - "* return ix86_output_call_insn (insn, operands[0]);" +{ + rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0)); + return ix86_output_call_insn (insn, fnaddr); +} [(set_attr "type" "call")]) ;; Since sibcall never returns, we can only use call-clobbered register @@ -12127,7 +12130,10 @@ (match_operand:SI 1 "GOT_memory_operand" "Bg"))) (match_operand 2)))] "TARGET_X32" - "* return ix86_output_call_insn (insn, operands[1]);" +{ + rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0)); + return ix86_output_call_insn (insn, fnaddr); +} [(set_attr "type" "callv")]) ;; Since sibcall never returns, we can only use call-clobbered register