From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2140) id 9C2A93858D37; Wed, 2 Mar 2022 17:14:11 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9C2A93858D37 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Alexandre Oliva To: gcc-cvs@gcc.gnu.org Subject: [gcc r12-7453] Undo multi-word optional reloads correctly X-Act-Checkin: gcc X-Git-Author: Alexandre Oliva X-Git-Refname: refs/heads/master X-Git-Oldrev: dbaabd06aaf4a1b0f2a20671c39148a0bd6ccf0e X-Git-Newrev: 12f8dc0b642db5edc702f252af1a5231606b29db Message-Id: <20220302171411.9C2A93858D37@sourceware.org> Date: Wed, 2 Mar 2022 17:14:11 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 02 Mar 2022 17:14:11 -0000 https://gcc.gnu.org/g:12f8dc0b642db5edc702f252af1a5231606b29db commit r12-7453-g12f8dc0b642db5edc702f252af1a5231606b29db Author: Alexandre Oliva Date: Wed Mar 2 14:13:06 2022 -0300 Undo multi-word optional reloads correctly Unlike e.g. remove_inheritance_pseudos, undo_optional_reloads didn't deal with subregs, so instead of removing multi-word moves, it replaced the reload pseudo with the original pseudo. Besides the redundant move, that retained the clobber of the dest, that starts a multi-word move. After the remap, the sequence that should have become a no-op move starts by clobbering the original pseudo and then moving its pieces onto themselves. The problem is the clobber: it makes earlier sets of the original pseudo to be regarded as dead: if the optional reload sequence was an output reload, the insn for which the output reload was attempted may be regarded as dead and deleted. I've arranged for undo_optional_reloads to accept SUBREGs and use get_regno, like remove_inheritance_pseudo, adjusted its insn-removal loop to tolerate iterating over a removed clobber, and added logic to catch any left-over reload clobbers that could trigger the problem. for gcc/ChangeLog * lra-constraints.cc (undo_optional_reloads): Recognize and drop insns of multi-word move sequences, tolerate removal iteration on an already-removed clobber, and refuse to substitute original pseudos into clobbers. Diff: --- gcc/lra-constraints.cc | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc index b2c4590153c..5cd89e7eedd 100644 --- a/gcc/lra-constraints.cc +++ b/gcc/lra-constraints.cc @@ -7261,15 +7261,17 @@ undo_optional_reloads (void) continue; src = SET_SRC (set); dest = SET_DEST (set); - if (! REG_P (src) || ! REG_P (dest)) + if ((! REG_P (src) && ! SUBREG_P (src)) + || (! REG_P (dest) && ! SUBREG_P (dest))) continue; - if (REGNO (dest) == regno + if (get_regno (dest) == (int) regno /* Ignore insn for optional reloads itself. */ - && REGNO (lra_reg_info[regno].restore_rtx) != REGNO (src) + && (get_regno (lra_reg_info[regno].restore_rtx) + != get_regno (src)) /* Check only inheritance on last inheritance pass. */ - && (int) REGNO (src) >= new_regno_start + && get_regno (src) >= new_regno_start /* Check that the optional reload was inherited. */ - && bitmap_bit_p (&lra_inheritance_pseudos, REGNO (src))) + && bitmap_bit_p (&lra_inheritance_pseudos, get_regno (src))) { keep_p = true; break; @@ -7291,18 +7293,22 @@ undo_optional_reloads (void) bitmap_copy (insn_bitmap, &lra_reg_info[regno].insn_bitmap); EXECUTE_IF_SET_IN_BITMAP (insn_bitmap, 0, uid, bi2) { + /* We may have already removed a clobber. */ + if (!lra_insn_recog_data[uid]) + continue; insn = lra_insn_recog_data[uid]->insn; if ((set = single_set (insn)) != NULL_RTX) { src = SET_SRC (set); dest = SET_DEST (set); - if (REG_P (src) && REG_P (dest) - && ((REGNO (src) == regno - && (REGNO (lra_reg_info[regno].restore_rtx) - == REGNO (dest))) - || (REGNO (dest) == regno - && (REGNO (lra_reg_info[regno].restore_rtx) - == REGNO (src))))) + if ((REG_P (src) || SUBREG_P (src)) + && (REG_P (dest) || SUBREG_P (dest)) + && ((get_regno (src) == (int) regno + && (get_regno (lra_reg_info[regno].restore_rtx) + == get_regno (dest))) + || (get_regno (dest) == (int) regno + && (get_regno (lra_reg_info[regno].restore_rtx) + == get_regno (src))))) { if (lra_dump_file != NULL) { @@ -7310,7 +7316,7 @@ undo_optional_reloads (void) INSN_UID (insn)); dump_insn_slim (lra_dump_file, insn); } - delete_move_and_clobber (insn, REGNO (dest)); + delete_move_and_clobber (insn, get_regno (dest)); continue; } /* We should not worry about generation memory-memory @@ -7319,6 +7325,11 @@ undo_optional_reloads (void) we remove the inheritance pseudo and the optional reload. */ } + if (GET_CODE (PATTERN (insn)) == CLOBBER + && REG_P (SET_DEST (insn)) + && get_regno (SET_DEST (insn)) == (int) regno) + /* Refuse to remap clobbers to preexisting pseudos. */ + gcc_unreachable (); lra_substitute_pseudo_within_insn (insn, regno, lra_reg_info[regno].restore_rtx, false); lra_update_insn_regno_info (insn);