https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117191
--- Comment #7 from denisc at gcc dot gnu.org --- I'm sorry for the strange previous comment. The right one. Probably I found a bug. The bug appears after the dse2 pass. The dse2 pass removes necessary insns. (ie insn 554) They are removed because LRA doesn't remove CLOBBER insn. (insn 202) The old "good" reload has a special "pass" for removing such CLOBBER insns. 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; } ------------------------------------------------------------------------------- The fix is simple: diff --git a/gcc/lra-spills.cc b/gcc/lra-spills.cc index c149c3388cd..db591e1d12c 100644 --- a/gcc/lra-spills.cc +++ b/gcc/lra-spills.cc @@ -741,10 +741,19 @@ lra_final_code_change (void) delete_insn (insn); continue; } - if (GET_CODE (pat) == CLOBBER && LRA_TEMP_CLOBBER_P (pat)) + if (GET_CODE (pat) == CLOBBER + && (LRA_TEMP_CLOBBER_P (pat) + || (!MEM_P (XEXP (pat, 0)) + || GET_MODE (XEXP (pat, 0)) != BLKmode + || (GET_CODE (XEXP (XEXP (pat, 0), 0)) != SCRATCH + && XEXP (XEXP (pat, 0), 0) + != stack_pointer_rtx)))) { - /* Remove clobbers temporarily created in LRA. We don't - need them anymore and don't want to waste compiler + /* Remove clobbers temporarily created in LRA and clobbers with + registers spilled to memory except those that refer to the + return value and the special mem:BLK CLOBBERs added to prevent + the scheduler from misarranging variable-array code. + We don't need them anymore and don't want to waste compiler time processing them in a few subsequent passes. */ lra_invalidate_insn_data (insn); delete_insn (insn);