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

--- Comment #15 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The trunk branch has been updated by Richard Sandiford <[email protected]>:

https://gcc.gnu.org/g:0399019276a0e26e5e06cd13296d724bb7afa87b

commit r16-7861-g0399019276a0e26e5e06cd13296d724bb7afa87b
Author: Richard Sandiford <[email protected]>
Date:   Tue Mar 3 08:55:38 2026 +0000

    rtl-ssa: Ensure live-out uses before redefinitions [PR123786]

    This patch fixes cases in which:

    (1) a register is live in to an EBB;
    (2) the register is live out of at least one BB in the EBB; and
    (3) the register is redefined by a later BB in the same EBB.

    We were supposed to create live-out uses for (2), so that the redefinition
    in (3) cannot be moved up into the live range of (1).

    The patch does this by collecting all definitions in second and
    subsequence BBs of an EBB.  It then creates degenerate phis for those
    registers that do not naturally need phis.  For speed and simplicity,
    the patch does not check for (2).  If a register is live in to the EBB,
    then it must be used somewhere, either in the EBB itself or in a
    successor outside of the EBB.  A degenerate phi would eventually
    be needed in either case.

    This requires moving append_bb earlier, so that add_phi_nodes can
    iterate over the BBs in an EBB.

    live_out_value contained an on-the-fly optimisation to remove redundant
    phis.  That was a mistake.  live_out_value can be called multiple times
    for the same quantity.  Replacing a phi on-the-fly messes up bookkeeping
    for second and subsequent calls.

    The live_out_value optimisation was mostly geared towards memory.
    As an experiment, I added an assert for when the optimisation applied
    to registers.  It only fired once in an x86_64-linux-gnu bootstrap &
    regression test, in gcc.dg/tree-prof/split-1.c.  That's a very poor
    (but unsurprising) return.  And the optimisation will still be done
    eventually anyway, during the phi simplification phase.  Doing it on
    the fly was just supposed to allow the phi's memory to be reused.

    The patch therefore moves the optimisation into add_phi_nodes and
    restricts it to memory (for which it does make a difference).

    gcc/
            PR rtl-optimization/123786
            * rtl-ssa/functions.h (function_info::live_out_value): Delete.
            (function_info::create_degenerate_phi): New overload.
            * rtl-ssa/blocks.cc (all_uses_are_live_out_uses): Delete.
            (function_info::live_out_value): Likewise.
            (function_info::replace_phi): Keep live-out uses if they are
followed
            by a definition in the same EBB.
            (function_info::create_degenerate_phi): New overload, extracted
            from create_reg_use.
            (function_info::add_phi_nodes): Ensure that there is a phi for
            every live input that is redefined by a second or subsequent
            block in the EBB.  Record that such phis need live-out uses.
            (function_info::record_block_live_out): Use
look_through_degenerate_phi
            rather than live_out_value when setting phi inputs.  Remove use of
            live_out_value for live-out uses.  Inline the old handling of
            bb_mem_live_out.
            (function_info::start_block): Move append_bb call to...
            (function_info::create_ebbs): ...here.
            * rtl-ssa/insns.cc (function_info::create_reg_use): Use the new
            create_degenerate_phi overload.

    gcc/testsuite/
            PR rtl-optimization/123786
            * gcc.target/aarch64/pr123786.c: New test.

    Co-authored-by: Artemiy Volkov <[email protected]>

Reply via email to