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))))