http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49163
Kazumoto Kojima <kkojima at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Known to work| |4.6.1 Keywords| |ice-on-valid-code Last reconfirmed| |2011.06.02 11:54:58 CC| |kkojima at gcc dot gnu.org Ever Confirmed|0 |1 Summary|ICE in change_address_1, at |[4.7 Regression] [SH] ICE |emit-rtl.c:1936 |in change_address_1, at | |emit-rtl.c:1936 Known to fail| |4.7.0 --- Comment #1 from Kazumoto Kojima <kkojima at gcc dot gnu.org> 2011-06-02 11:54:58 UTC --- It seems that the insn like (insn 66 141 110 4 (set (reg:SI 4 r4) (sign_extend:SI (subreg:QI (mem/s/v/u/c:DI (plus:SI (reg/f:SI 7 r7 [192]) (const_int 12 [0xc])) [3 s2array[1][0].f0+0 S8 A32]) 0))) iii.c:39 164 {*extendqisi2_compact} (expr_list:REG_DEAD (reg/f:SI 7 r7 [192]) (nil))) which is an intermediate insn in reload causes this ICE. SH makes the memory address like (plus (reg) (const_int)) invalid for HI/QImode because mov.b can take only R0 as the other operand for that memory and GCC can't handle such case well. I'm testing the patch below which makes constraints for some move insns more rigid about invalid addresses of this type. diff -uprN ORIG/trunk/gcc/config/sh/predicates.md trunk/gcc/config/sh/predicates.md --- ORIG/trunk/gcc/config/sh/predicates.md 2010-04-12 09:52:36.000000000 +0900 +++ trunk/gcc/config/sh/predicates.md 2011-06-02 10:17:40.000000000 +0900 @@ -394,6 +394,18 @@ return 0; } + if ((mode == QImode || mode == HImode) + && (MEM_P (op) + || (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op))))) + { + rtx x = XEXP ((MEM_P (op) ? op : SUBREG_REG (op)), 0); + + if (GET_CODE (x) == PLUS + && REG_P (XEXP (x, 0)) + && CONST_INT_P (XEXP (x, 1))) + return sh_legitimate_index_p (mode, XEXP (x, 1)); + } + if (TARGET_SHMEDIA && (GET_CODE (op) == PARALLEL || GET_CODE (op) == CONST_VECTOR) && sh_rep_vec (op, mode)) @@ -419,6 +431,18 @@ && ! (high_life_started || reload_completed)) return 0; + if ((mode == QImode || mode == HImode) + && (MEM_P (op) + || (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op))))) + { + rtx x = XEXP ((MEM_P (op) ? op : SUBREG_REG (op)), 0); + + if (GET_CODE (x) == PLUS + && REG_P (XEXP (x, 0)) + && CONST_INT_P (XEXP (x, 1))) + return sh_legitimate_index_p (mode, XEXP (x, 1)); + } + return general_operand (op, mode); })