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

Reply via email to