From fe1486e118d72d660284af43cb739e20d094b585 Mon Sep 17 00:00:00 2001 From: Denis Chertykov Date: Fri, 15 Nov 2024 00:50:36 +0400 Subject: [PATCH] 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. --- gcc/lra-spills.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gcc/lra-spills.cc b/gcc/lra-spills.cc index c149c3388cd..3f5c8d2bcb0 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",