From patchwork Thu Dec 1 17:40:10 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Preudhomme X-Patchwork-Id: 86122 Delivered-To: patch@linaro.org Received: by 10.140.20.101 with SMTP id 92csp804246qgi; Thu, 1 Dec 2016 09:40:40 -0800 (PST) X-Received: by 10.84.206.37 with SMTP id f34mr86791006ple.35.1480614040459; Thu, 01 Dec 2016 09:40:40 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id b189si935038pgc.242.2016.12.01.09.40.40 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 01 Dec 2016 09:40:40 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-443246-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-443246-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-443246-patch=linaro.org@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=vQIx8xa1wJ5ExCd4qtdOX0nOCi6rXSYQApOUiQysHZtZuDuFhV ZDUOIoU2ljkXwYOEB2jczQDa3Cy7j2iCMiFvWjvHyjRy78JIsGYlxVp4mnfyOd9L sebaq/8x3KCAxxkq7Daz1I0PGsGqGpOEyoPhIadi40l8iZzknpCWwGHVo= 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:to :from:subject:message-id:date:mime-version:content-type; s= default; bh=oOPaxO19t/wM4RpmmMpCgrrULcM=; b=L0siuOHFwbGbH2uPi0So gcrIaKALYezjr1p83yjxKqgVm9WCVWvesRrUTSVGLMCWoGHSRV7GWloumgSyzaoo XB0brnBZ4uBYw0/eU5BxxTXJCOEcK6u8kjXuWKCxdx6FJ/dv0m1PbcVggtD4RKeB SNtZG09yoUq4Zg3+T71twmo= Received: (qmail 74440 invoked by alias); 1 Dec 2016 17:40:24 -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 74429 invoked by uid 89); 1 Dec 2016 17:40:23 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.8 required=5.0 tests=BAYES_00, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=Living X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 01 Dec 2016 17:40:13 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id C86DB16; Thu, 1 Dec 2016 09:40:11 -0800 (PST) Received: from [10.2.206.52] (usa-sjc-imap-foss1.foss.arm.com [10.72.51.249]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 557283F318; Thu, 1 Dec 2016 09:40:11 -0800 (PST) To: Vladimir Makarov , "gcc-patches@gcc.gnu.org" From: Thomas Preudhomme Subject: [PATCH, GCC/LRA] Fix PR78617: Fix conflict detection in rematerialization Message-ID: Date: Thu, 1 Dec 2016 17:40:10 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.3.0 MIME-Version: 1.0 X-IsSubscribed: yes Hi, When considering a candidate for rematerialization, LRA verifies if the candidate clobbers a live register before going forward with the rematerialization (see code starting with comment "Check clobbers do not kill something living."). To do this check, the set of live registers at any given instruction needs to be maintained. This is done by initializing the set of live registers when starting the forward scan of instruction in a basic block and updating the set by looking at REG_DEAD notes and destination register at the end of an iteration of the scan loop. However the initialization suffers from 2 issues: 1) it is done from the live out set rather than live in (uses df_get_live_out (bb)) 2) it ignores pseudo registers that have already been allocated a hard register (uses REG_SET_TO_HARD_REG_SET that only looks at hard register and does not look at reg_renumber for pseudo registers) This patch changes the code to use df_get_live_in (bb) to initialize the live_hard_regs variable using a loop to check reg_renumber for pseudo registers. Please let me know if there is a macro to do that, I failed to find one. ChangeLog entries are as follow: gcc/testsuite/ChangeLog: 2016-12-01 Thomas Preud'homme PR rtl-optimization/78617 * gcc.c-torture/execute/pr78617.c: New test. gcc/ChangeLog: 2016-12-01 Thomas Preud'homme PR rtl-optimization/78617 * lra-remat.c (do_remat): Initialize live_hard_regs from live in registers, also setting hard registers mapped to pseudo registers. Note however that as explained in the problem report, the testcase does not trigger the bug on GCC 7 due to better optimization before LRA rematerialization is reached. Testing: testsuite shows no regression when run using: + an arm-none-eabi GCC cross-compiler targeting Cortex-M0 and Cortex-M3 + a bootstrapped arm-linux-gnueabihf GCC native compiler + a bootstrapped x86_64-linux-gnu GCC native compiler Is this ok for stage3? Best regards, Thomas diff --git a/gcc/lra-remat.c b/gcc/lra-remat.c index f01c6644c428fd9b5efdf6cc98788e5f6fadba62..cdd7057f602098d33ec3acfdaaac66556640bd82 100644 --- a/gcc/lra-remat.c +++ b/gcc/lra-remat.c @@ -1047,6 +1047,7 @@ update_scratch_ops (rtx_insn *remat_insn) static bool do_remat (void) { + unsigned regno; rtx_insn *insn; basic_block bb; bitmap_head avail_cands; @@ -1054,12 +1055,21 @@ do_remat (void) bool changed_p = false; /* Living hard regs and hard registers of living pseudos. */ HARD_REG_SET live_hard_regs; + bitmap_iterator bi; bitmap_initialize (&avail_cands, ®_obstack); bitmap_initialize (&active_cands, ®_obstack); FOR_EACH_BB_FN (bb, cfun) { - REG_SET_TO_HARD_REG_SET (live_hard_regs, df_get_live_out (bb)); + CLEAR_HARD_REG_SET (live_hard_regs); + EXECUTE_IF_SET_IN_BITMAP (df_get_live_in (bb), 0, regno, bi) + { + int hard_regno = regno < FIRST_PSEUDO_REGISTER + ? regno + : reg_renumber[regno]; + if (hard_regno >= 0) + SET_HARD_REG_BIT (live_hard_regs, hard_regno); + } bitmap_and (&avail_cands, &get_remat_bb_data (bb)->avin_cands, &get_remat_bb_data (bb)->livein_cands); /* Activating insns are always in the same block as their corresponding diff --git a/gcc/testsuite/gcc.c-torture/execute/pr78617.c b/gcc/testsuite/gcc.c-torture/execute/pr78617.c new file mode 100644 index 0000000000000000000000000000000000000000..89c4f6dea8cb507b963f91debb94cbe16eb1db90 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr78617.c @@ -0,0 +1,25 @@ +int a = 0; +int d = 1; +int f = 1; + +int fn1() { + return a || 1 >> a; +} + +int fn2(int p1, int p2) { + return p2 >= 2 ? p1 : p1 >> 1; +} + +int fn3(int p1) { + return d ^ p1; +} + +int fn4(int p1, int p2) { + return fn3(!d > fn2((f = fn1() - 1000) || p2, p1)); +} + +int main() { + if (fn4(0, 0) != 1) + __builtin_abort (); + return 0; +}