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

--- Comment #12 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <ja...@gcc.gnu.org>:

https://gcc.gnu.org/g:9c4397cafc5ded9b008a92a55d4e5207e1c2e4e4

commit r15-6943-g9c4397cafc5ded9b008a92a55d4e5207e1c2e4e4
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Thu Jan 16 09:20:15 2025 +0100

    tailc: Virtually undo IPA-VRP return value optimization for tail calls
[PR118430]

    When we have return somefn (whatever); where somefn is normally tail
    callable and IPA-VRP determines somefn returns a singleton range, VRP
    just changes the IL to
      somefn (whatever);
      return 42;
    (or whatever the value in that range is).  The introduction of IPA-VRP
    return value tracking then effectively regresses the tail call
optimization.
    This is even more important if the call is [[gnu::musttail]].

    So, the following patch queries IPA-VRP whether a function returns
singleton
    range and if so and the value returned is identical to that, marks the
    call as [tail call] anyway.  If expansion decides it can't use the tail
    call, we'll still expand the return 42; or similar statement, and if it
    decides it can use the tail call, that part will be ignored and we'll emit
    normal tail call.

    The reason it works is that the expand pass relies on the tailc pass to
    do its job properly.
    E.g. when we have
      <bb 2> [local count: 1073741824]:
      foo (x_2(D));
      baz (&v);
      v ={v} {CLOBBER(eos)};
      bar (x_2(D)); [tail call]
      return 1;
    when expand_gimple_basic_block handles the bar (x_2(D)); call, it uses
              if (call_stmt && gimple_call_tail_p (call_stmt))
                {
                  bool can_fallthru;
                  new_bb = expand_gimple_tailcall (bb, call_stmt,
&can_fallthru);
                  if (new_bb)
                    {
                      if (can_fallthru)
                        bb = new_bb;
                      else
                        {
                          currently_expanding_gimple_stmt = NULL;
                          return new_bb;
                        }
                    }
                }
    As it is actually tail callable during expansion of the bar (x_2(D)); call
    stmt, expand_gimple_tailbb returns non-NULL and sets can_fallthru to false,
    plus emits
    ;; bar (x_2(D)); [tail call]

    (insn 11 10 12 2 (set (reg:SI 5 di)
            (reg/v:SI 99 [ x ])) "pr118430.c":35:10 -1
         (nil))

    (call_insn/j 12 11 13 2 (set (reg:SI 0 ax)
            (call (mem:QI (symbol_ref:DI ("bar") [flags 0x3]  <function_decl
0x7fb39020bd00 bar>) [0 bar S1 A8])
                (const_int 0 [0]))) "pr118430.c":35:10 -1
         (expr_list:REG_CALL_DECL (symbol_ref:DI ("bar") [flags 0x3] 
<function_decl 0x7fb39020bd00 bar>)
            (expr_list:REG_EH_REGION (const_int 0 [0])
                (nil)))
        (expr_list:SI (use (reg:SI 5 di))
            (nil)))

    (barrier 13 12 0)
    Because it doesn't fallthru, no further statements in the same bb are
    expanded.  Now, if the bb with return happened to be in some other basic
    block from the [tail call], it could be expanded but because the bb with
    tail call ends with a barrier, it doesn't fall thru there and if nothing
    else could reach it, we'd remove the unreachable bb RSN.

    2025-01-16  Jakub Jelinek  <ja...@redhat.com>
                Andrew Pinski  <quic_apin...@quicinc.com>

            PR tree-optimization/118430
            * tree-tailcall.cc: Include gimple-range.h, alloc-pool.h, sreal.h,
            symbol-summary.h, ipa-cp.h and ipa-prop.h.
            (find_tail_calls): If ass_var is NULL and ret_var is not, check if
            IPA-VRP has not found singleton return range for it.  In that case,
            don't punt if ret_var is the only value in that range.  Adjust the
            maybe_error_musttail message otherwise to diagnose different value
            being returned from the caller and callee rather than using return
            slot.  Formatting fixes.

            * c-c++-common/musttail14.c: New test.
            * c-c++-common/pr118430.c: New test.

Reply via email to