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

--- Comment #4 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Richard Sandiford <rsand...@gcc.gnu.org>:

https://gcc.gnu.org/g:e648e57efca6ce6d751ef8c2038608817b514fb4

commit r10-6247-ge648e57efca6ce6d751ef8c2038608817b514fb4
Author: Richard Sandiford <richard.sandif...@arm.com>
Date:   Sat Jan 18 12:41:48 2020 +0000

    lra: Stop registers being incorrectly marked live [PR92989]

    lra_assign has an assert to make sure that no pseudo is allocated
    to a conflicting hard register.  It used to be restricted to
    !flag_ipa_ra, but in g:a1e6ee38e708ef2bdef4 I'd enabled it for
    flag_ipa_ra too.  It then tripped while building libstdc++
    for mips-mti-linux.

    The failure was due to code at the end of process_bb_lives.  For an
    abnormal/EH edge, we need to make sure that all pseudos that are live
    on entry to the destination conflict with all hard registers that are
    clobbered by an abnormal call return.  The usual way to do this would
    be to simulate a clobber of the hard registers, by making them live and
    them making them dead again.  Making the registers live creates the
    conflict; making them dead again restores the correct live set for
    whatever follows.

    However, process_bb_lives skips the second step (making the registers
    dead again) at the start of a BB, presumably on the basis that there's
    no further code that needs a correct live set.  The problem for the PR
    is that that wasn't quite true in practice.  There was code further
    down process_bb_lives that updated the live-in set of the BB for some
    registers, and this live set was "contaminated" by registers that
    weren't live but that created conflicts.  This information then got
    propagated to other blocks, so that registers that were made live
    purely to create a conflict at the start of the EH receiver then became
    needlessly live throughout preceding blocks.  This in turn created a
    fake conflict with pseudos in those blocks, invalidating the choices
    made by IRA.

    The easiest fix seems to be to update the live-in set *before* adding
    the fake live registers.  An alternative would be to simulate the full
    clobber, but that seems a bit wasteful.

    2020-01-27  Richard Sandiford  <richard.sandif...@arm.com>

    gcc/
        PR rtl-optimization/92989
        * lra-lives.c (process_bb_lives): Update the live-in set before
        processing additional clobbers.

Reply via email to