re PR target/53988 ([SH] tst Rm,Rn not used for QI/HImode)
authorOleg Endo <olegendo@gcc.gnu.org>
Mon, 19 Jan 2015 22:35:53 +0000 (22:35 +0000)
committerOleg Endo <olegendo@gcc.gnu.org>
Mon, 19 Jan 2015 22:35:53 +0000 (22:35 +0000)
gcc/
PR target/53988
* config/sh/sh-protos.h (sh_find_set_of_reg): Make sure not to return
nullptr for insn when reaching the first insn.
* config/sh/sh.c (sh_unspec_insn_p): Rewrite using subrtx_iterator.
(sh_insn_operands_modified_between_p): Add nullptr check.
(sh_find_extending_set_of_reg): Fix log message.  Don't accept
sign extending mem load if the insn contains any UNSPEC or
UNSPEC_VOLATILE.

From-SVN: r219864

gcc/ChangeLog
gcc/config/sh/sh-protos.h
gcc/config/sh/sh.c

index e126ea03d7ae29c22a31c27ff0f57c5b35301d95..7078d40cfa9705b5e19f717c9e1831dfb8760761 100644 (file)
@@ -1,3 +1,14 @@
+2015-01-19  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/53988
+       * config/sh/sh-protos.h (sh_find_set_of_reg): Make sure not to return
+       nullptr for insn when reaching the first insn.
+       * config/sh/sh.c (sh_unspec_insn_p): Rewrite using subrtx_iterator.
+       (sh_insn_operands_modified_between_p): Add nullptr check.
+       (sh_find_extending_set_of_reg): Fix log message.  Don't accept
+       sign extending mem load if the insn contains any UNSPEC or
+       UNSPEC_VOLATILE.
+
 2015-01-19  Jan Hubicka  <hubicka@ucw.cz>
 
        * params.def (inline-unit-growth): Drop to 15%.
index 181062c07838fcf1afe21a111c3b8f90857cd343..bc2b3b30667cafbaea3232631e6c78e7f6ae9ea9 100644 (file)
@@ -192,11 +192,13 @@ sh_find_set_of_reg (rtx reg, rtx_insn* insn, F stepfunc,
   if (!REG_P (reg) || insn == NULL_RTX)
     return result;
 
+  rtx_insn* previnsn = insn;
+
   for (result.insn = stepfunc (insn); result.insn != NULL_RTX;
-       result.insn = stepfunc (result.insn))
+       previnsn = result.insn, result.insn = stepfunc (result.insn))
     {
       if (BARRIER_P (result.insn))
-       return result;
+       break;
       if (!NONJUMP_INSN_P (result.insn))
        continue;
       if (reg_set_p (reg, result.insn))
@@ -204,7 +206,7 @@ sh_find_set_of_reg (rtx reg, rtx_insn* insn, F stepfunc,
          result.set_rtx = set_of (reg, result.insn);
 
          if (result.set_rtx == NULL_RTX || GET_CODE (result.set_rtx) != SET)
-           return result;
+           break;
 
          result.set_src = XEXP (result.set_rtx, 1);
 
@@ -220,10 +222,19 @@ sh_find_set_of_reg (rtx reg, rtx_insn* insn, F stepfunc,
              continue;
            }
 
-         return result;
+         break;
        }
     }
 
+  /* If the loop above stopped at the first insn in the list,
+     result.insn will be null.  Use the insn from the previous iteration
+     in this case.  */
+  if (result.insn == NULL)
+    result.insn = previnsn;
+
+  if (result.set_src != NULL)
+    gcc_assert (result.insn != NULL && result.set_rtx != NULL);
+
   return result;
 }
 
index 9e1a09e7dd2295935000d593674ccef1ce1b2cd7..bde95f6a587e45e010a43904ff98d21c543ebca4 100644 (file)
@@ -13738,22 +13738,15 @@ sh_find_equiv_gbr_addr (rtx_insn* insn, rtx mem)
 /* Return true if the specified insn contains any UNSPECs or
    UNSPEC_VOLATILEs.  */
 static bool
-sh_unspec_insn_p (rtx_insn* insn)
+sh_unspec_insn_p (rtx x)
 {
-  bool result = false;
-
-  struct note_uses_func
-  {
-    static void
-    func (rtx* x, void* data)
-    {
-      if (GET_CODE (*x) == UNSPEC || GET_CODE (*x) == UNSPEC_VOLATILE)
-       *(static_cast<bool*> (data)) = true;
-    }
-  };
+  subrtx_iterator::array_type array;
+  FOR_EACH_SUBRTX (i, array, x, ALL)
+    if (*i != NULL
+       && (GET_CODE (*i) == UNSPEC || GET_CODE (*i) == UNSPEC_VOLATILE))
+      return true;
 
-  note_uses (&PATTERN (insn), note_uses_func::func, &result);
-  return result;
+  return false;
 }
 
 /* Return true if the register operands of the specified insn are modified
@@ -13770,7 +13763,8 @@ sh_insn_operands_modified_between_p (rtx_insn* operands_insn,
 
   subrtx_iterator::array_type array;
   FOR_EACH_SUBRTX (i, array, SET_SRC (s), ALL)
-    if ((REG_P (*i) || SUBREG_P (*i)) && reg_set_between_p (*i, from, to))
+    if (*i != NULL &&
+       ((REG_P (*i) || SUBREG_P (*i)) && reg_set_between_p (*i, from, to)))
       return true;
 
   return false;
@@ -13927,7 +13921,7 @@ sh_find_extending_set_of_reg (rtx reg, rtx_insn* curr_insn)
          || GET_CODE (result.set_src) == ZERO_EXTEND)
        {
          if (dump_file)
-           fprintf (dump_file, "sh_find_szexnteded_reg: reg %d is "
+           fprintf (dump_file, "sh_find_extending_set_of_reg: reg %d is "
                                "explicitly sign/zero extended in insn %d\n",
                                REGNO (reg), INSN_UID (result.insn));
          result.from_mode = GET_MODE (XEXP (result.set_src, 0));
@@ -13935,7 +13929,8 @@ sh_find_extending_set_of_reg (rtx reg, rtx_insn* curr_insn)
        }
       else if (MEM_P (result.set_src)
               && (GET_MODE (result.set_src) == QImode
-                  || GET_MODE (result.set_src) == HImode))
+                  || GET_MODE (result.set_src) == HImode)
+              && !sh_unspec_insn_p (result.insn))
        {
          /* On SH QIHImode memory loads always sign extend.  However, in
             some cases where it seems that the higher bits are not