In the i386 backend, tailcalls are incorrectly disallowed in PIC mode for
calls via function pointers on the basis that indirect calls, like direct
calls, would go via PLT and thus require %ebx to point to GOT -- but that is
not true.  Quoting Rich Felker who reported the bug,

  "For PLT slots in the non-PIE main executable, %ebx is not required at all.
  PLT slots in PIE or shared libraries need %ebx, but a function pointer can
  never evaluate to such a PLT slot; it always evaluates to the nominal address
  of the function which is the same in all DSOs and therefore fundamentally
  cannot depend on the address of the GOT in the calling DSO"

As far as I can see it's simply a mistake that was there from day 1 (comment 4
in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65753 points to original patch).

Bootstrapped and regtested on 32-bit x86, OK for trunk?
(the comment before the condition will need to be adjusted too, i.e.
s/optimize any indirect call, or a direct call/optimize any direct call/ )

        PR target/65753
        * config/i386/i386.c (ix86_function_ok_for_sibcall): Allow PIC sibcalls
        via function pointers.

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 3263656..f29e053 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -5448,13 +5448,13 @@ ix86_function_ok_for_sibcall (tree decl, tree exp)
   /* 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.)  */
   if (!TARGET_MACHO
       && !TARGET_64BIT
       && flag_pic
-      && (!decl || !targetm.binds_local_p (decl)))
+      && (decl && !targetm.binds_local_p (decl)))
     return false;
 
   /* If we need to align the outgoing stack, then sibcalling would
      unalign the stack, which may break the called function.  */
   if (ix86_minimum_incoming_stack_boundary (true)
       < PREFERRED_STACK_BOUNDARY)

Reply via email to