This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH i386] PR65753: allow PIC tail calls via function pointers
- From: Alexander Monakov <amonakov at ispras dot ru>
- To: Jan Hubicka <hubicka at ucw dot cz>
- Cc: gcc-patches at gcc dot gnu dot org, Rich Felker <dalias at libc dot org>
- Date: Mon, 11 May 2015 19:11:18 +0300 (MSK)
- Subject: Re: [PATCH i386] PR65753: allow PIC tail calls via function pointers
- Authentication-results: sourceware.org; auth=none
- References: <1430757479-14241-1-git-send-email-amonakov at ispras dot ru> <1430757479-14241-2-git-send-email-amonakov at ispras dot ru> <20150510163753 dot GF9659 at atrey dot karlin dot mff dot cuni dot cz>
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!
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;