diff mbox

[i386] PR65753: allow PIC tail calls via function pointers

Message ID alpine.LNX.2.11.1505111850590.22867@monopod.intra.ispras.ru
State New
Headers show

Commit Message

Alexander Monakov May 11, 2015, 4:11 p.m. UTC
On Sun, 10 May 2015, Jan Hubicka wrote:
> You probably need to update comment here. I wonder what happens when we optimize
> indirect call to direct call to global function at RTL level? I suppose we are
> safe here, because at RTL level we explicitly represent if we refer to PLT entry
> or the functionaddress itself and we never optimize one to the other?
> 
> Patch is OK if you make sure that this works and update the comment.

I think we are safe: to have things break we'd have to have a GOT-relative
memory load be combined with a branch on the RTL level, and GOT loads have
UNSPEC_GOT.  I have used the following example to try to induce failure:

  void foo(void);
  void bar()
  {
    void (*p)(void) = foo;
    p();
  }

With the following options: 

  gcc -fPIC -m32 -O -foptimize-sibling-calls -fno-tree-ccp -fno-tree-copy-prop
  -fno-tree-fre -fno-tree-dominator-opts -fno-tree-ter

GCC has indirect call after pass_expand.  Without -fPIC it is transformed into
direct call in pass_combine, with -fPIC it is kept as is.

I've added a testcase.  Below is what I'm checking in.  Thanks!
diff mbox

Patch

Index: testsuite/gcc.target/i386/pr65753.c
===================================================================
--- testsuite/gcc.target/i386/pr65753.c	(revision 0)
+++ testsuite/gcc.target/i386/pr65753.c	(revision 0)
@@ -0,0 +1,8 @@ 
+/* { dg-do compile } */
+/* { dg-options "-fPIC -O" } */
+/* { dg-final { scan-assembler-not "call" } } */
+
+void foo(void (*bar)(void))
+{
+  bar();
+}
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 223002)
+++ config/i386/i386.c	(working copy)
@@ -5473,12 +5473,12 @@ 
   rtx a, b;
 
   /* If we are generating position-independent code, we cannot sibcall
-     optimize any indirect call, or a direct call to a global function,
-     as the PLT requires %ebx be live. (Darwin does not have a PLT.)  */
+     optimize direct calls to global functions, as the PLT requires
+     %ebx be live. (Darwin does not have a PLT.)  */
   if (!TARGET_MACHO
       && !TARGET_64BIT
       && flag_pic
-      && (!decl || !targetm.binds_local_p (decl)))
+      && decl && !targetm.binds_local_p (decl))
     return false;