http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54699
--- Comment #3 from Oleg Endo <olegendo at gcc dot gnu.org> 2012-09-30 21:09:29 UTC --- Doing this... Index: gcc/config/sh/sh.c =================================================================== --- gcc/config/sh/sh.c (revision 191865) +++ gcc/config/sh/sh.c (working copy) @@ -10079,6 +10079,9 @@ static bool sh_legitimate_address_p (enum machine_mode mode, rtx x, bool strict) { + if (reload_completed) + return true; + if (MAYBE_BASE_REGISTER_RTX_P (x, strict)) return true; else if ((GET_CODE (x) == POST_INC || GET_CODE (x) == PRE_DEC) makes the ICE go away. However, I have not tested this for any other consequences. This one is probably the better fix (max_mov_insn_displacement): Index: gcc/config/sh/sh.c =================================================================== --- gcc/config/sh/sh.c (revision 191865) +++ gcc/config/sh/sh.c (working copy) @@ -3457,21 +3457,20 @@ /* SH2A supports FPU move insns with 12 bit displacements. Other variants to do not support any kind of displacements for - FPU move insns. */ - if (! consider_sh2a && TARGET_FPU_ANY && GET_MODE_CLASS (mode) == MODE_FLOAT) - return 0; - else - { - const int mov_insn_sz = mov_insn_size (mode, consider_sh2a); - const int mode_sz = GET_MODE_SIZE (mode); - int r = 15 * mov_insn_sz * disp_scale; + FPU move insns. However, in the worst case, we can still use SImode + loads/stores with displacement, such as in the movsf_ie pattern instead + of true FPU move insns. It's just going to be more expensive because + additional gp reg <-> fpu reg moves have to be used for that. */ + const int mov_insn_sz = mov_insn_size (mode, consider_sh2a); + const int mode_sz = GET_MODE_SIZE (mode); + int r = 15 * mov_insn_sz * disp_scale; - /* If the mov insn will be split into multiple loads/stores, the - maximum possible displacement is a bit smaller. */ - if (mode_sz > mov_insn_sz) - r -= mode_sz - mov_insn_sz; - return r; - } + /* If the mov insn will be split into multiple loads/stores, the + maximum possible displacement is a bit smaller. */ + if (mode_sz > mov_insn_sz) + r -= mode_sz - mov_insn_sz; + + return r; } /* Determine the alignment mask for a move insn of the This makes the ICE go away, but it will wrongly output SH2A fmov.s insns such as fmov.s @(16,r7),fr3 when compiling for SH4. The movsf_ie insn looks a bit ... complicated ... and probably should be split into multiple insns to be able to handle such cases. Maybe there's an even easier solution, but I can't imagine one at the moment.