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

Reply via email to