------- Comment #1 from kkojima at gcc dot gnu dot org 2007-04-26 08:17 ------- I've confirmed that the test case fails also on trunk. sh.c:output_stack_adjust tries to find a register for a constant to unwind the frame and wrongly finds a frame register itself in the problematic case. I'm testing the attached patch.
diff -uprN ORIG/trunk/gcc/config/sh/sh.c LOCAL/trunk/gcc/config/sh/sh.c --- ORIG/trunk/gcc/config/sh/sh.c 2007-03-22 09:50:40.000000000 +0900 +++ LOCAL/trunk/gcc/config/sh/sh.c 2007-04-26 08:06:16.000000000 +0900 @@ -5619,7 +5619,13 @@ output_stack_adjust (int size, rtx reg, temp = scavenge_reg (&temps); } if (temp < 0 && live_regs_mask) - temp = scavenge_reg (live_regs_mask); + { + HARD_REG_SET temps; + + COPY_HARD_REG_SET (temps, *live_regs_mask); + CLEAR_HARD_REG_BIT (temps, REGNO (reg)); + temp = scavenge_reg (&temps); + } if (temp < 0) { rtx adj_reg, tmp_reg, mem; @@ -5668,6 +5674,9 @@ output_stack_adjust (int size, rtx reg, emit_move_insn (adj_reg, mem); mem = gen_tmp_stack_mem (Pmode, gen_rtx_POST_INC (Pmode, reg)); emit_move_insn (tmp_reg, mem); + /* Tell flow the insns that pop r4/r5 aren't dead. */ + emit_insn (gen_rtx_USE (VOIDmode, tmp_reg)); + emit_insn (gen_rtx_USE (VOIDmode, adj_reg)); return; } const_reg = gen_rtx_REG (GET_MODE (reg), temp); -- kkojima at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |kkojima at gcc dot gnu dot | |org Status|UNCONFIRMED |NEW Ever Confirmed|0 |1 Known to fail|4.1.0 |4.1.0 4.2.0 4.3.0 Last reconfirmed|0000-00-00 00:00:00 |2007-04-26 08:17:49 date| | Summary|Program giving segmentation |[4.1/4.2/4.3 Regression] SH: |fault with '-O2' |wrong epilogue for sibling |optimization. |calls http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31701