http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54065
--- Comment #1 from Oleg Endo <olegendo at gcc dot gnu.org> 2012-08-23 23:09:07 UTC --- On rev 190580 I've tried out replacing the sh_legitimize_address function with the following one: sh_legitimize_address (rtx x, rtx oldx, enum machine_mode mode) { if (flag_pic) x = legitimize_pic_address (oldx, mode, NULL_RTX); if (TARGET_SHMEDIA) return x; if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1)) && BASE_REGISTER_RTX_P (XEXP (x, 0))) { /* SH2A has displacement floating-point loads and stores. On everything else change the address to use index addressing. */ if (FLOAT_MODE_P (mode) && TARGET_FPU_ANY && ! TARGET_SH2A) { rtx reg = gen_reg_rtx (Pmode); emit_insn (gen_move_insn (reg, XEXP (x, 1))); return gen_rtx_PLUS (Pmode, reg, XEXP (x, 0)); } struct disp_adjust adj = sh_find_mov_disp_adjust (mode, INTVAL (XEXP (x, 1))); if (adj.offset_adjust != NULL_RTX && adj.mov_disp != NULL_RTX) { rtx sum = expand_binop (Pmode, add_optab, XEXP (x, 0), adj.offset_adjust, NULL_RTX, 0, OPTAB_LIB_WIDEN); return gen_rtx_PLUS (Pmode, sum, adj.mov_disp); } } return x; } This 'fixes' the issue mentioned in the description. Looking at CSiBE result-size there is a small overall improvement, but there are also quite some code size increases. It seems difficult to select the optimal addressing mode for these kind of situations without looking at the surrounding code. It also seems that transforming every displacement address into an index address will make it difficult for the auto-inc-dec pass to find opportunities, as it is not smart enough to undo the indexed address transformation. Last but not least, the indexed address increases pressure on R0 of course.