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

--- Comment #11 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Denis Chertykov <den...@gcc.gnu.org>:

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

commit r15-5293-gfe1486e118d72d660284af43cb739e20d094b585
Author: Denis Chertykov <cherty...@gmail.com>
Date:   Fri Nov 15 00:50:36 2024 +0400

    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.

Reply via email to