Properly handle -fno-plt in ix86_expand_callheads/hjl/pr67215/master
commit47284e287700b7f2f5f879f855883953430b0239
authorH.J. Lu <hjl.tools@gmail.com>
Sun, 16 Aug 2015 11:46:20 +0000 (16 04:46 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Mon, 31 Aug 2015 16:53:06 +0000 (31 09:53 -0700)
tree395aedb3c6a3b45ed14f533d7b07837d6aecae7e
parente091399d2b960846f03e89c1790a314b5929057f
Properly handle -fno-plt in ix86_expand_call

It boils down to that -fno-plt should convert calling an external
function, foo, from

call foo@PLT

to

call *foo@GOT

to avoid one extra direct branch to PLT.  The proper place for this is
in backend during expanding a function call.  The backend already takes
care of many details for calling an external function, like setting up
a PIC register.  Using the GOT slot instead of PLT slot is just one of
those details.  For x86, it should be done in ix86_expand_call, not
prepare_call_address and hoping for the best, which doesn't always
happen.  Also non-PIC case can only be handled in backend.

This patch reverts -fno-plt in prepare_call_address and handles it in
ix86_expand_call.  Other backends may need similar changes to support
-fno-plt.  Alternately, we can introduce a target hook to indicate
whether an external function should be called via register for -fno-plt
so that i386 backend can disable it in prepare_call_address.

sibcall_memory_operand is also updated to accept the GOT slot so that

call *foo@GOT(%reg)

can be generated by ix86_expand_call for 32-bit and 64-bit large model.

gcc/

PR target/67215
* calls.c (prepare_call_address): Don't handle -fno-plt here.
* config/i386/i386.c (ix86_expand_call): Generate indirect call
via GOT for -fno-plt.  Support indirect call via GOT for x32.

gcc/testsuite/

PR target/67215
* gcc.target/i386/pr67215-1.c: New test.
* gcc.target/i386/pr67215-2.c: Likewise.
gcc/calls.c
gcc/config/i386/i386.c
gcc/testsuite/gcc.target/i386/pr67215-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr67215-2.c [new file with mode: 0644]