From patchwork Mon Feb 12 15:59:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Segher Boessenkool X-Patchwork-Id: 872125 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-473084-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="sTtVufhf"; dkim-atps=neutral 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 3zg9Ms3tdhz9s7f for ; Tue, 13 Feb 2018 02:59:20 +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:from :to:cc:subject:date:message-id; q=dns; s=default; b=kF8d8oleRgxf LBc1QvIBaGQQsDRF0+USRgJbHXxSzAaMo49HFCdsGcN8iBh2rSpb40rrVfXvPHLB rH7pfyeA93c8T7i34O9aMP2Lc5lbjUOBAFEtg2/ZLgwId8DF2z4YLgZNhPlp3cPb N5PoKLwUf4dn3Nf6vYrhGbsrxJvnl/s= 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:from :to:cc:subject:date:message-id; s=default; bh=qubkhH0w70ifMpX/VO KrIB94OUg=; b=sTtVufhf2y0+cstg+vRN/slJHh1rRAdRY5SQCC+GTAm83oFe2+ aqvIKdcs/USnjkhik3bGg8mpNvC8bPssX5Q1roegshcAs3fXKV/H0BPPJLr0d/sT m+32uOk393GJeZrFsqqylOlWIA91xF29crUo4jUE47T16W8KctRw1mv/c= Received: (qmail 110746 invoked by alias); 12 Feb 2018 15:59:13 -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 110736 invoked by uid 89); 12 Feb 2018 15:59:13 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-24.3 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy= X-HELO: gcc1-power7.osuosl.org Received: from gcc1-power7.osuosl.org (HELO gcc1-power7.osuosl.org) (140.211.15.137) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 12 Feb 2018 15:59:11 +0000 Received: by gcc1-power7.osuosl.org (Postfix, from userid 10019) id E5EAE1240359; Mon, 12 Feb 2018 15:59:09 +0000 (UTC) From: Segher Boessenkool To: gcc-patches@gcc.gnu.org Cc: Segher Boessenkool Subject: [PATCH] combine: Update links correctly for new I2 (PR84169) Date: Mon, 12 Feb 2018 15:59:05 +0000 Message-Id: <8a65498338913b3902abaf7ac325df4ce230cd08.1518389741.git.segher@kernel.crashing.org> X-IsSubscribed: yes If there is a LOG_LINK between two insns, this means those two insns can be combined, as far as dataflow is concerned. There never should be a LOG_LINK between two unrelated insns. If there is one, combine will try to combine the insns without doing all the needed checks if the earlier destination is used before the later insn, etc. Unfortunately we do not update the LOG_LINKs correctly in some cases. This patch fixes at least some of those cases. This fixes the PR's testcase on aarch64. Also tested on 30+ cross compiler, and on powerpc64-linux {-m32,-m64}. Will test on x86_64 as well before committing. Segher 2018-02-12 Segher Boessenkool PR rtl-optimization/84169 * combine.c (try_combine): New variable split_i2i3. Set it to true if we generated a parallel as new i3 and we split that to new i2 and i3 instructions. Handle split_i2i3 similar to swap_i2i3: scan the LOG_LINKs of i3 to see which of those need to link to i2 now. Link those to i2, not i1. Partially rewrite this scan code. --- gcc/combine.c | 55 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/gcc/combine.c b/gcc/combine.c index 870bc77..204368e 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -2737,6 +2737,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, /* Notes that I1, I2 or I3 is a MULT operation. */ int have_mult = 0; int swap_i2i3 = 0; + int split_i2i3 = 0; int changed_i3_dest = 0; int maxreg; @@ -4167,6 +4168,9 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, } insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); + + if (insn_code_number >= 0) + split_i2i3 = 1; } } @@ -4334,44 +4338,45 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, if (swap_i2i3) { - rtx_insn *insn; - struct insn_link *link; - rtx ni2dest; - /* I3 now uses what used to be its destination and which is now I2's destination. This requires us to do a few adjustments. */ PATTERN (i3) = newpat; adjust_for_new_dest (i3); + } - /* We need a LOG_LINK from I3 to I2. But we used to have one, - so we still will. + if (swap_i2i3 || split_i2i3) + { + /* We might need a LOG_LINK from I3 to I2. But then we used to + have one, so we still will. However, some later insn might be using I2's dest and have - a LOG_LINK pointing at I3. We must remove this link. - The simplest way to remove the link is to point it at I1, - which we know will be a NOTE. */ + a LOG_LINK pointing at I3. We should change it to point at + I2 instead. */ /* newi2pat is usually a SET here; however, recog_for_combine might have added some clobbers. */ - if (GET_CODE (newi2pat) == PARALLEL) - ni2dest = SET_DEST (XVECEXP (newi2pat, 0, 0)); - else - ni2dest = SET_DEST (newi2pat); + rtx x = newi2pat; + if (GET_CODE (x) == PARALLEL) + x = XVECEXP (newi2pat, 0, 0); - for (insn = NEXT_INSN (i3); - insn && (this_basic_block->next_bb == EXIT_BLOCK_PTR_FOR_FN (cfun) - || insn != BB_HEAD (this_basic_block->next_bb)); + unsigned int regno = REGNO (SET_DEST (x)); + + bool done = false; + for (rtx_insn *insn = NEXT_INSN (i3); + !done + && insn + && NONDEBUG_INSN_P (insn) + && BLOCK_FOR_INSN (insn) == this_basic_block; insn = NEXT_INSN (insn)) { - if (NONDEBUG_INSN_P (insn) - && reg_referenced_p (ni2dest, PATTERN (insn))) - { - FOR_EACH_LOG_LINK (link, insn) - if (link->insn == i3) - link->insn = i1; - - break; - } + struct insn_link *link; + FOR_EACH_LOG_LINK (link, insn) + if (link->insn == i3 && link->regno == regno) + { + link->insn = i2; + done = true; + break; + } } }