Commit b151091d by Oleg Endo

re PR target/53988 ([SH] tst Rm,Rn not used for QI/HImode)

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
parent c2db7204
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> 2015-01-19 Jan Hubicka <hubicka@ucw.cz>
* params.def (inline-unit-growth): Drop to 15%. * params.def (inline-unit-growth): Drop to 15%.
......
...@@ -192,11 +192,13 @@ sh_find_set_of_reg (rtx reg, rtx_insn* insn, F stepfunc, ...@@ -192,11 +192,13 @@ sh_find_set_of_reg (rtx reg, rtx_insn* insn, F stepfunc,
if (!REG_P (reg) || insn == NULL_RTX) if (!REG_P (reg) || insn == NULL_RTX)
return result; return result;
rtx_insn* previnsn = insn;
for (result.insn = stepfunc (insn); result.insn != NULL_RTX; 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)) if (BARRIER_P (result.insn))
return result; break;
if (!NONJUMP_INSN_P (result.insn)) if (!NONJUMP_INSN_P (result.insn))
continue; continue;
if (reg_set_p (reg, result.insn)) if (reg_set_p (reg, result.insn))
...@@ -204,7 +206,7 @@ sh_find_set_of_reg (rtx reg, rtx_insn* insn, F stepfunc, ...@@ -204,7 +206,7 @@ sh_find_set_of_reg (rtx reg, rtx_insn* insn, F stepfunc,
result.set_rtx = set_of (reg, result.insn); result.set_rtx = set_of (reg, result.insn);
if (result.set_rtx == NULL_RTX || GET_CODE (result.set_rtx) != SET) if (result.set_rtx == NULL_RTX || GET_CODE (result.set_rtx) != SET)
return result; break;
result.set_src = XEXP (result.set_rtx, 1); result.set_src = XEXP (result.set_rtx, 1);
...@@ -220,10 +222,19 @@ sh_find_set_of_reg (rtx reg, rtx_insn* insn, F stepfunc, ...@@ -220,10 +222,19 @@ sh_find_set_of_reg (rtx reg, rtx_insn* insn, F stepfunc,
continue; 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; return result;
} }
......
...@@ -13738,22 +13738,15 @@ sh_find_equiv_gbr_addr (rtx_insn* insn, rtx mem) ...@@ -13738,22 +13738,15 @@ sh_find_equiv_gbr_addr (rtx_insn* insn, rtx mem)
/* Return true if the specified insn contains any UNSPECs or /* Return true if the specified insn contains any UNSPECs or
UNSPEC_VOLATILEs. */ UNSPEC_VOLATILEs. */
static bool static bool
sh_unspec_insn_p (rtx_insn* insn) sh_unspec_insn_p (rtx x)
{ {
bool result = false; subrtx_iterator::array_type array;
FOR_EACH_SUBRTX (i, array, x, ALL)
struct note_uses_func if (*i != NULL
{ && (GET_CODE (*i) == UNSPEC || GET_CODE (*i) == UNSPEC_VOLATILE))
static void return true;
func (rtx* x, void* data)
{
if (GET_CODE (*x) == UNSPEC || GET_CODE (*x) == UNSPEC_VOLATILE)
*(static_cast<bool*> (data)) = true;
}
};
note_uses (&PATTERN (insn), note_uses_func::func, &result); return false;
return result;
} }
/* Return true if the register operands of the specified insn are modified /* 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, ...@@ -13770,7 +13763,8 @@ sh_insn_operands_modified_between_p (rtx_insn* operands_insn,
subrtx_iterator::array_type array; subrtx_iterator::array_type array;
FOR_EACH_SUBRTX (i, array, SET_SRC (s), ALL) 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 true;
return false; return false;
...@@ -13927,7 +13921,7 @@ sh_find_extending_set_of_reg (rtx reg, rtx_insn* curr_insn) ...@@ -13927,7 +13921,7 @@ sh_find_extending_set_of_reg (rtx reg, rtx_insn* curr_insn)
|| GET_CODE (result.set_src) == ZERO_EXTEND) || GET_CODE (result.set_src) == ZERO_EXTEND)
{ {
if (dump_file) 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", "explicitly sign/zero extended in insn %d\n",
REGNO (reg), INSN_UID (result.insn)); REGNO (reg), INSN_UID (result.insn));
result.from_mode = GET_MODE (XEXP (result.set_src, 0)); 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) ...@@ -13935,7 +13929,8 @@ sh_find_extending_set_of_reg (rtx reg, rtx_insn* curr_insn)
} }
else if (MEM_P (result.set_src) else if (MEM_P (result.set_src)
&& (GET_MODE (result.set_src) == QImode && (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 /* On SH QIHImode memory loads always sign extend. However, in
some cases where it seems that the higher bits are not some cases where it seems that the higher bits are not
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment