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

--- Comment #3 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Michael Matz <m...@gcc.gnu.org>:

https://gcc.gnu.org/g:85bee4f77b1b0ebe68b3efe0c356b7d5fb006c4d

commit r15-4242-g85bee4f77b1b0ebe68b3efe0c356b7d5fb006c4d
Author: Michael Matz <m...@suse.de>
Date:   Thu Oct 10 16:36:51 2024 +0200

    Fix PR116650: check all regs in regrename targets

    (this came up for m68k vs. LRA, but is a generic problem)

    Regrename wants to use new registers for certain def-use chains.
    For validity of replacements it needs to check that the selected
    candidates are unused up to then.  That's done in check_new_reg_p.
    But if it so happens that the new register needs more hardregs
    than the old register (which happens if the target allows inter-bank
    moves and the mode is something like a DFmode that needs to be placed
    into a SImode reg-pair), then check_new_reg_p only checks the
    first of those registers for free-ness.

    This is caused by that function looking up the number of necessary
    hardregs only in terms of the old hardreg number.  It of course needs
    to do that in terms of the new candidate regnumber.  The symptom is that
    regrename sometimes clobbers the higher numbered registers of such a
    regrename target pair.  This patch fixes that problem.

    (In the particular case of the bug report it was LRA that left over a
    inter-bank move instruction that triggers regrename, ultimately causing
    the mis-compile.  Reload didn't do that, but in general we of course
    can't rely on such moves not happening if the target allows them.)

    This also shows a general confusion in that function and the target hook
    interface here:

      for (i = nregs - 1; i >= 0; --)
        ...
        || ! HARD_REGNO_RENAME_OK (reg + i, new_reg + i))

    it uses nregs in a way that requires it to be the same between old and
    new register.  The problem is that the target hook only gets register
    numbers, when it instead should get a mode and register numbers and
    would be called only for the first but not for subsequent registers.
    I've looked at a number of definitions of that target hook and I think
    that this is currently harmless in the sense that it would merely rule
    out some potential reg-renames that would in fact be okay to do.  So I'm
    not changing the target hook interface here and hence that problem
    remains unfixed.

            PR rtl-optimization/116650
            * regrename.cc (check_new_reg_p): Calculate nregs in terms of
            the new candidate register.

Reply via email to