https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62111
Kazumoto Kojima <kkojima at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |kkojima at gcc dot gnu.org --- Comment #5 from Kazumoto Kojima <kkojima at gcc dot gnu.org> --- I'm trying to find out what is going on. Here is a part of RTL dump for the test case before reload: (insn 6 5 9 2 (set (reg:DI 160 [ D.1463 ]) (mem/c:DI (plus:DI (reg/f:DI 166) (const_int 8 [0x8])) [2 empty_zero_page+8 S8 A64])) xxx.c:15 282 {*movdi_media_nofpu} (expr_list:REG_EQUIV (mem/c:DI (plus:DI (reg/f:DI 166) (const_int 8 [0x8])) [2 empty_zero_page+8 S8 A64]) (nil))) (insn 9 6 28 2 (set (reg:SI 169 [ D.1464 ]) (zero_extend:SI (truncate:HI (reg:DI 160 [ D.1463 ])))) xxx.c:15 226 {*zero_extendhisi2_media} (nil)) and reload combines these two insns into the insn (insn 9 6 28 2 (set (reg:SI 2 r2 [orig:169 D.1464 ] [169]) (zero_extend:SI (truncate:HI (mem/c:DI (plus:DI (reg/f:DI 10 r10 [166]) (const_int 8 [0x8])) [2 empty_zero_page+8 S8 A64])))) xxx.c:15 226 {*zero_extendhisi2_media} (nil)) which results this ICE. It looks that reload recognizes the last insn is a valid *zero_extendhisi2_media insn: (define_insn "*zero_extendhisi2_media" [(set (match_operand:SI 0 "register_operand" "=r,r") (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))] ... even though general_extend_operand doesn't permit (truncate (mem ...)). An easy workaround might be to disable truncate in general_extend_operand before reload. --- gcc/config/sh/predicates.md.orig 2014-08-02 11:55:29.228875715 +0900 +++ gcc/config/sh/predicates.md 2014-08-17 08:30:20.439326569 +0900 @@ -398,7 +398,7 @@ (define_predicate "general_extend_operand" (match_code "subreg,reg,mem,truncate") { - if (GET_CODE (op) == TRUNCATE) + if (reload_completed && GET_CODE (op) == TRUNCATE) return arith_operand (op, mode); if (MEM_P (op) || (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op))))