[prev in list] [next in list] [prev in thread] [next in thread] 

List:       gcc-bugs
Subject:    [Bug target/54699] [4.8 Regression] [SH] gfortran.dg/class_array_9.f03 ICEs
From:       "olegendo at gcc dot gnu.org" <gcc-bugzilla () gcc ! gnu ! org>
Date:       2012-09-30 21:09:29
Message-ID: bug-54699-4-G8kxeNSU98 () http ! gcc ! gnu ! org/bugzilla/
[Download RAW message or body]


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54699

--- Comment #3 from Oleg Endo <olegendo at gcc dot gnu.org> 2012-09-30 21:09:29 UTC ---
Doing this...

Index: gcc/config/sh/sh.c
===================================================================
--- gcc/config/sh/sh.c    (revision 191865)
+++ gcc/config/sh/sh.c    (working copy)
@@ -10079,6 +10079,9 @@
 static bool
 sh_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
 {
+  if (reload_completed)
+    return true;
+
   if (MAYBE_BASE_REGISTER_RTX_P (x, strict))
     return true;
   else if ((GET_CODE (x) == POST_INC || GET_CODE (x) == PRE_DEC)


makes the ICE go away.  However, I have not tested this for any other
consequences.

This one is probably the better fix (max_mov_insn_displacement):

Index: gcc/config/sh/sh.c
===================================================================
--- gcc/config/sh/sh.c    (revision 191865)
+++ gcc/config/sh/sh.c    (working copy)
@@ -3457,21 +3457,20 @@

   /* SH2A supports FPU move insns with 12 bit displacements.
      Other variants to do not support any kind of displacements for
-     FPU move insns.  */
-  if (! consider_sh2a && TARGET_FPU_ANY && GET_MODE_CLASS (mode) ==
MODE_FLOAT)
-    return 0;
-  else
-    {
-      const int mov_insn_sz = mov_insn_size (mode, consider_sh2a);
-      const int mode_sz = GET_MODE_SIZE (mode);
-      int r = 15 * mov_insn_sz * disp_scale;
+     FPU move insns.  However, in the worst case, we can still use SImode
+     loads/stores with displacement, such as in the movsf_ie pattern instead
+     of true FPU move insns.  It's just going to be more expensive because
+     additional gp reg <-> fpu reg moves have to be used for that.  */
+  const int mov_insn_sz = mov_insn_size (mode, consider_sh2a);
+  const int mode_sz = GET_MODE_SIZE (mode);
+  int r = 15 * mov_insn_sz * disp_scale;

-      /* If the mov insn will be split into multiple loads/stores, the
-     maximum possible displacement is a bit smaller.  */
-      if (mode_sz > mov_insn_sz)
-    r -= mode_sz - mov_insn_sz;
-      return r;
-    }
+  /* If the mov insn will be split into multiple loads/stores, the
+     maximum possible displacement is a bit smaller.  */
+  if (mode_sz > mov_insn_sz)
+    r -= mode_sz - mov_insn_sz;
+
+  return r;
 }

 /* Determine the alignment mask for a move insn of the


This makes the ICE go away, but it will wrongly output SH2A fmov.s insns such
as
    fmov.s    @(16,r7),fr3

when compiling for SH4.

The movsf_ie insn looks a bit ... complicated ... and probably should be split
into multiple insns to be able to handle such cases.

Maybe there's an even easier solution, but I can't imagine one at the moment.
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic