From b151091dca19708ce7b51fcdf4fffd4b45a831c5 Mon Sep 17 00:00:00 2001 From: Oleg Endo Date: Mon, 19 Jan 2015 22:35:53 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 11 +++++++++++ gcc/config/sh/sh-protos.h | 19 +++++++++++++++---- gcc/config/sh/sh.c | 29 ++++++++++++----------------- 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e126ea03d7a..7078d40cfa9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2015-01-19 Oleg Endo + + 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 * params.def (inline-unit-growth): Drop to 15%. diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h index 181062c0783..bc2b3b30667 100644 --- a/gcc/config/sh/sh-protos.h +++ b/gcc/config/sh/sh-protos.h @@ -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; } diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 9e1a09e7dd2..bde95f6a587 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -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 (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 -- 2.30.2