]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
The fix for PR117191
authorDenis Chertykov <chertykov@gmail.com>
Thu, 14 Nov 2024 20:50:36 +0000 (00:50 +0400)
committerDenis Chertykov <chertykov@gmail.com>
Thu, 14 Nov 2024 20:50:36 +0000 (00:50 +0400)
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.

gcc/lra-spills.cc

index c149c3388cdb6c562b76efa23ef124a00f7fd4c6..3f5c8d2bcb00d502671e82a7c863447359356958 100644 (file)
@@ -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",