https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97267

--- Comment #1 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Alan Modra <amo...@gcc.gnu.org>:

https://gcc.gnu.org/g:18963d3bee780cd8a6477ad5a198410758ec4e60

commit r11-4634-g18963d3bee780cd8a6477ad5a198410758ec4e60
Author: Alan Modra <amo...@gmail.com>
Date:   Sun Sep 27 19:11:58 2020 +0930

    can_implement_as_sibling_call_p REG_PARM_STACK_SPACE check

    This moves an #ifdef block of code from calls.c to
    targetm.function_ok_for_sibcall.  Only two targets, x86 and rs6000,
    define REG_PARM_STACK_SPACE or OUTGOING_REG_PARM_STACK_SPACE macros
    that might vary depending on the called function.  Macros like
    UNITS_PER_WORD don't change over a function boundary, nor does the
    MIPS ABI, nor does TARGET_64BIT on PA-RISC.  Other targets are even
    more trivially proven to not need the calls.c code.

    Besides cleaning up a small piece of #ifdef code, the motivation for
    this patch is to allow tail calls on PowerPC for functions that
    require less reg_parm_stack_space than their caller.  The original
    code in calls.c only permitted tail calls when exactly equal, but on
    PowerPC we can tail call if the callee has less or equal
    REG_PARM_STACK_SPACE than the caller, as demonstrated by the
    testcase.  So we should use

      /* If reg parm stack space increases, we cannot sibcall.  */
      if (REG_PARM_STACK_SPACE (decl ? decl : fntype)
          > INCOMING_REG_PARM_STACK_SPACE (current_function_decl))

    and note the change to use INCOMING_REG_PARM_STACK_SPACE.
    REG_PARM_STACK_SPACE has always been wrong there for PowerPC.  See
    https://gcc.gnu.org/pipermail/gcc-patches/2014-May/389867.html for why
    if you're curious.  Not that it matters, because PowerPC can do
    without this check entirely, relying on a stack slot test in generic
    code.

    a) The generic code checks that arg passing stack in the callee is not
       greater than that in the caller, and,
    b) ELFv2 only allocates reg_parm_stack_space when some parameter is
       passed on the stack.
    Point (b) means that zero reg_parm_stack_space implies zero stack
    space, and non-zero reg_parm_stack_space implies non-zero stack
    space.  So the case of 0 reg_parm_stack_space in the caller and 64 in
    the callee will be caught by (a).

    gcc/
            PR middle-end/97267
            * calls.h (maybe_complain_about_tail_call): Declare.
            * calls.c (maybe_complain_about_tail_call): Make global.
            (can_implement_as_sibling_call_p): Delete reg_parm_stack_space
            param.  Adjust caller.  Move REG_PARM_STACK_SPACE check to..
            * config/i386/i386.c (ix86_function_ok_for_sibcall): ..here.

    gcc/testsuite/
            PR middle-end/97267
            * gcc.target/powerpc/pr97267.c: New test.
  • [Bug middle-end/97267] Missed t... cvs-commit at gcc dot gnu.org via Gcc-bugs

Reply via email to