From patchwork Mon Feb 23 23:27:41 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kaz Kojima X-Patchwork-Id: 442701 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id D222D140151 for ; Tue, 24 Feb 2015 10:27:57 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :message-id:to:subject:from:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=tVm5u8xem7aAPgyW 63YK/6OAgLvywNSYe1iIrJr6keINwOwxJVcHTJvwUXnblDSWhB4TrMdJmYSCy9CJ 7OMTyz0lqlQVKHwPnX3Xd4ili1iAMC81sqY+3MreaSMVvPgWkCcwacpfJ1sTsGec uGWG1C7tPgb6jrPAsulAGgMhYis= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :message-id:to:subject:from:mime-version:content-type :content-transfer-encoding; s=default; bh=xZpRLrSRUXBP5GtfXJOqJx W9dfA=; b=YY/3ewE366ohSpuy6t2ThL78DhDj3tKA6QW3MuJ9Vr5bgO5KDvHywB ZLPL9Vt3OJ5zNg2PMFdtjQ/f9eQhF51vUNRYYzX/Ql6d8KRyIq1W9QhWXmARnsgS +cjyxVcnf++RwNfirZPi5W020pJG7AbY4dW+/0HVX5KrlSeCtgYcY= Received: (qmail 15010 invoked by alias); 23 Feb 2015 23:27:50 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 15001 invoked by uid 89); 23 Feb 2015 23:27:49 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.6 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mo-sw.iij4u.or.jp Received: from mo-sw1501.iij4u.or.jp (HELO mo-sw.iij4u.or.jp) (210.130.239.241) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Mon, 23 Feb 2015 23:27:47 +0000 Received: by mo-sw.iij4u.or.jp (4u-mo-sw1501) id t1NNRgsE003186; Tue, 24 Feb 2015 08:27:43 +0900 Received: from localhost (132.8.30.125.dy.iij4u.or.jp [125.30.8.132]) by mbox.iij4u.or.jp (4u-mbox1501) id t1NNRg9E021055; Tue, 24 Feb 2015 08:27:42 +0900 Date: Tue, 24 Feb 2015 08:27:41 +0900 (JST) Message-Id: <20150224.082741.492096416.kkojima@rr.iij4u.or.jp> To: gcc-patches@gcc.gnu.org Subject: [PATCH committed] [SH] Fix PR target/65153 From: Kaz Kojima Mime-Version: 1.0 X-IsSubscribed: yes The attached patch is to fix PR target/65153 which is a 4.9.2 regression and latent on trunk. The patch removes a problematic peephole and sh.c:replace_n_hard_rtx of which that peephole is the last user. Oleg shows that the patch doesn't give any significant differences with CSiBE tests. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65153 for details. Tested on sh4-unknwon-linux-gnu with no new failures. Committed on trunk. I'll backport it to 4.9 branch later. Regards, kaz --- 2015-02-23 Kaz Kojima PR target/65153 * config/sh/sh.md (movsicc_true+3): Remove peephole. * config/sh/sh-protos.h (replace_n_hard_rtx): Don't declare. * config/sh/sh.c (replace_n_hard_rtx): Remove. diff --git a/config/sh/sh-protos.h b/config/sh/sh-protos.h index 1d8ba1d..c706e74 100644 --- a/config/sh/sh-protos.h +++ b/config/sh/sh-protos.h @@ -384,7 +384,6 @@ extern void sh_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, signed int, machine_mode); extern rtx sh_dwarf_register_span (rtx); -extern rtx replace_n_hard_rtx (rtx, rtx *, int , int); extern int shmedia_cleanup_truncate (rtx); extern bool sh_contains_memref_p (rtx); diff --git a/config/sh/sh.c b/config/sh/sh.c index 7c9d8e2..02c6176 100644 --- a/config/sh/sh.c +++ b/config/sh/sh.c @@ -13015,146 +13015,6 @@ sh_init_cumulative_args (CUMULATIVE_ARGS * pcum, } } -/* Replace any occurrence of FROM(n) in X with TO(n). The function does - not enter into CONST_DOUBLE for the replace. - - Note that copying is not done so X must not be shared unless all copies - are to be modified. - - This is like replace_rtx, except that we operate on N_REPLACEMENTS - replacements simultaneously - FROM(n) is replacements[n*2] and to(n) is - replacements[n*2+1] - and that we take mode changes into account. - - If a replacement is ambiguous, return NULL_RTX. - - If MODIFY is zero, don't modify any rtl in place, - just return zero or nonzero for failure / success. */ -rtx -replace_n_hard_rtx (rtx x, rtx *replacements, int n_replacements, int modify) -{ - int i, j; - const char *fmt; - - /* The following prevents loops occurrence when we change MEM in - CONST_DOUBLE onto the same CONST_DOUBLE. */ - if (x != NULL_RTX && GET_CODE (x) == CONST_DOUBLE) - return x; - - for (i = n_replacements - 1; i >= 0 ; i--) - if (x == replacements[i*2] && GET_MODE (x) == GET_MODE (replacements[i*2+1])) - return replacements[i*2+1]; - - /* Allow this function to make replacements in EXPR_LISTs. */ - if (x == NULL_RTX) - return NULL_RTX; - - if (GET_CODE (x) == SUBREG) - { - rtx new_rtx = replace_n_hard_rtx (SUBREG_REG (x), replacements, - n_replacements, modify); - - if (CONST_INT_P (new_rtx)) - { - x = simplify_subreg (GET_MODE (x), new_rtx, - GET_MODE (SUBREG_REG (x)), - SUBREG_BYTE (x)); - if (! x) - abort (); - } - else if (modify) - SUBREG_REG (x) = new_rtx; - - return x; - } - else if (REG_P (x)) - { - unsigned regno = REGNO (x); - unsigned nregs = (regno < FIRST_PSEUDO_REGISTER - ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1); - rtx result = NULL_RTX; - - for (i = n_replacements - 1; i >= 0; i--) - { - rtx from = replacements[i*2]; - rtx to = replacements[i*2+1]; - unsigned from_regno, from_nregs, to_regno, new_regno; - - if (!REG_P (from)) - continue; - from_regno = REGNO (from); - from_nregs = (from_regno < FIRST_PSEUDO_REGISTER - ? HARD_REGNO_NREGS (from_regno, GET_MODE (from)) : 1); - if (regno < from_regno + from_nregs && regno + nregs > from_regno) - { - if (regno < from_regno - || regno + nregs > from_regno + nregs - || !REG_P (to) - || result) - return NULL_RTX; - to_regno = REGNO (to); - if (to_regno < FIRST_PSEUDO_REGISTER) - { - new_regno = regno + to_regno - from_regno; - if ((unsigned) HARD_REGNO_NREGS (new_regno, GET_MODE (x)) - != nregs) - return NULL_RTX; - result = gen_rtx_REG (GET_MODE (x), new_regno); - } - else if (GET_MODE (x) <= GET_MODE (to)) - result = gen_lowpart_common (GET_MODE (x), to); - else - result = gen_lowpart_SUBREG (GET_MODE (x), to); - } - } - return result ? result : x; - } - else if (GET_CODE (x) == ZERO_EXTEND) - { - rtx new_rtx = replace_n_hard_rtx (XEXP (x, 0), replacements, - n_replacements, modify); - - if (CONST_INT_P (new_rtx)) - { - x = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x), - new_rtx, GET_MODE (XEXP (x, 0))); - if (! x) - abort (); - } - else if (modify) - XEXP (x, 0) = new_rtx; - - return x; - } - - fmt = GET_RTX_FORMAT (GET_CODE (x)); - for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--) - { - rtx new_rtx; - - if (fmt[i] == 'e') - { - new_rtx = replace_n_hard_rtx (XEXP (x, i), replacements, - n_replacements, modify); - if (!new_rtx) - return NULL_RTX; - if (modify) - XEXP (x, i) = new_rtx; - } - else if (fmt[i] == 'E') - for (j = XVECLEN (x, i) - 1; j >= 0; j--) - { - new_rtx = replace_n_hard_rtx (XVECEXP (x, i, j), replacements, - n_replacements, modify); - if (!new_rtx) - return NULL_RTX; - if (modify) - XVECEXP (x, i, j) = new_rtx; - } - } - - return x; -} - rtx sh_gen_truncate (machine_mode mode, rtx x, int need_sign_ext) { diff --git a/config/sh/sh.md b/config/sh/sh.md index 94a01af..11b96d7 100644 --- a/config/sh/sh.md +++ b/config/sh/sh.md @@ -1706,76 +1706,6 @@ replace_rtx (operands[4], operands[0], operands[1]); }) -(define_peephole2 - [(set (match_operand 0 "any_register_operand" "") - (match_operand 1 "any_register_operand" "")) - (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" "")) - (set (match_operand 4 "" "") (match_operand 5 "" ""))] - "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2])) - <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0]))) - && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2]) - && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0]) - && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2]) - && ! reg_overlap_mentioned_p (operands[0], operands[3]) - && ! reg_overlap_mentioned_p (operands[2], operands[0]) - && ! reg_overlap_mentioned_p (operands[0], operands[1]) - && (REGNO_REG_CLASS (REGNO (operands[0])) - == REGNO_REG_CLASS (REGNO (operands[2]))) - && (REGNO_REG_CLASS (REGNO (operands[1])) - == REGNO_REG_CLASS (REGNO (operands[0])))" - [(set (match_dup 0) (match_dup 3)) - (set (match_dup 4) (match_dup 5))] -{ - rtx set1, set2; - rtx_insn *insn1, *insn2; - rtx replacements[4]; - - /* We want to replace occurrences of operands[0] with operands[1] and - operands[2] with operands[0] in operands[4]/operands[5]. - Doing just two replace_rtx calls naively would result in the second - replacement undoing all that the first did if operands[1] and operands[2] - are identical, so we must do this simultaneously. */ - replacements[0] = operands[0]; - replacements[1] = operands[1]; - replacements[2] = operands[2]; - replacements[3] = operands[0]; - if (!replace_n_hard_rtx (operands[5], replacements, 2, 0) - || !replace_n_hard_rtx (operands[4], replacements, 2, 0) - || !replace_n_hard_rtx (operands[2], replacements, 2, 0)) - FAIL; - - operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1); - replace_n_hard_rtx (operands[4], replacements, 2, 1); - operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1); - /* The operands array is aliased to recog_data.operand, which gets - clobbered by extract_insn, so finish with it now. */ - set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]); - set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]); - /* ??? The last insn might be a jump insn, but the generic peephole2 code - always uses emit_insn. */ - /* Check that we don't violate matching constraints or earlyclobbers. */ - basic_block bb = BLOCK_FOR_INSN (peep2_next_insn (2)); - insn1 = emit_insn (set1); - extract_insn (insn1); - if (! constrain_operands (1, get_preferred_alternatives (insn1, bb))) - goto failure; - insn2 = emit (set2); - if (GET_CODE (insn2) == BARRIER) - goto failure; - extract_insn (insn2); - if (! constrain_operands (1, get_preferred_alternatives (insn2, bb))) - { - failure: - std::swap (replacements[0], replacements[1]); - std::swap (replacements[2], replacements[3]); - replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1); - replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1); - replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1); - FAIL; - } - DONE; -}) - ;; The register allocator is rather clumsy in handling multi-way conditional ;; moves, so allow the combiner to make them, and we split them up after ;; reload. */