diff options
author | Denis Chertykov <chertykov@gmail.com> | 2024-11-15 00:50:36 +0400 |
---|---|---|
committer | Denis Chertykov <chertykov@gmail.com> | 2024-11-15 00:50:36 +0400 |
commit | fe1486e118d72d660284af43cb739e20d094b585 (patch) | |
tree | 7eb841cecf015119203cce27daaf7381e12bc31a | |
parent | 45cc42d6dc0642612e7076e95820438a1aab5479 (diff) | |
download | gcc-fe1486e118d72d660284af43cb739e20d094b585.zip gcc-fe1486e118d72d660284af43cb739e20d094b585.tar.gz gcc-fe1486e118d72d660284af43cb739e20d094b585.tar.bz2 |
The fix for PR117191
Wrong code appears after dse2 pass because it removes necessary insns.
(ie insn 554 - store to frame spill slot)
This happened because LRA pass doesn't cleanup the code exactly like reload does.
The reload1.c has a special pass for such cleanup.
The reload removes CLOBBER insns with spill slots like this:
(insn 202 184 186 7 (clobber (mem/c:TI (plus:HI (reg/f:HI 28 r28)
(const_int 1 [0x1])) [3 %sfp+1 S16 A8])) -1
(nil))
Fragment from reload1.c:
--------------------------------------------------------------------------------
reload_completed = 1;
/* Make a pass over all the insns and delete all USEs which we inserted
only to tag a REG_EQUAL note on them. Remove all REG_DEAD and REG_UNUSED
notes. Delete all CLOBBER insns, except those that refer to the return
value and the special mem:BLK CLOBBERs added to prevent the scheduler
from misarranging variable-array code, and simplify (subreg (reg))
operands. Strip and regenerate REG_INC notes that may have been moved
around. */
for (insn = first; insn; insn = NEXT_INSN (insn))
if (INSN_P (insn))
{
rtx *pnote;
if (CALL_P (insn))
replace_pseudos_in (& CALL_INSN_FUNCTION_USAGE (insn),
VOIDmode, CALL_INSN_FUNCTION_USAGE (insn));
if ((GET_CODE (PATTERN (insn)) == USE
/* We mark with QImode USEs introduced by reload itself. */
&& (GET_MODE (insn) == QImode
|| find_reg_note (insn, REG_EQUAL, NULL_RTX)))
|| (GET_CODE (PATTERN (insn)) == CLOBBER
&& (!MEM_P (XEXP (PATTERN (insn), 0))
|| GET_MODE (XEXP (PATTERN (insn), 0)) != BLKmode
|| (GET_CODE (XEXP (XEXP (PATTERN (insn), 0), 0)) != SCRATCH
&& XEXP (XEXP (PATTERN (insn), 0), 0)
!= stack_pointer_rtx))
&& (!REG_P (XEXP (PATTERN (insn), 0))
|| ! REG_FUNCTION_VALUE_P (XEXP (PATTERN (insn), 0)))))
{
delete_insn (insn);
continue;
}
--------------------------------------------------------------------------------
LRA have a similar place where it removes unnecessary insns, but not CLOBBER insns with
memory spill slots. It's `lra_final_code_change' function.
I just mark a CLOBBER insn with pseudo spilled to memory for removing it later together
with LRA temporary CLOBBER insns.
PR rtl-optimization/117191
gcc/
* lra-spills.cc (spill_pseudos): Mark a CLOBBER insn with pseudo
spilled to memory for removing it later together with LRA temporary
CLOBBER insns.
-rw-r--r-- | gcc/lra-spills.cc | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/gcc/lra-spills.cc b/gcc/lra-spills.cc index c149c338..3f5c8d2 100644 --- a/gcc/lra-spills.cc +++ b/gcc/lra-spills.cc @@ -537,6 +537,11 @@ spill_pseudos (void) break; } } + if (GET_CODE (PATTERN (insn)) == CLOBBER) + /* This is a CLOBBER insn with pseudo spilled to memory. + Mark it for removing it later together with LRA temporary + CLOBBER insns. */ + LRA_TEMP_CLOBBER_P (PATTERN (insn)) = 1; if (lra_dump_file != NULL) fprintf (lra_dump_file, "Changing spilled pseudos to memory in insn #%u\n", |