From patchwork Thu Oct 20 14:57:46 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kyrill Tkachov X-Patchwork-Id: 78523 Delivered-To: patch@linaro.org Received: by 10.140.97.247 with SMTP id m110csp826415qge; Thu, 20 Oct 2016 07:58:18 -0700 (PDT) X-Received: by 10.99.120.203 with SMTP id t194mr1698429pgc.17.1476975498041; Thu, 20 Oct 2016 07:58:18 -0700 (PDT) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id s80si45414087pfg.27.2016.10.20.07.58.17 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 20 Oct 2016 07:58:18 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-439140-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-439140-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-439140-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 :message-id:date:from:mime-version:to:subject:content-type; q= dns; s=default; b=qvX4peVxY3ovIz17XMb0CTdy3i0zg3uWGB3lFuRRbjwreZ vrKaueAF6f/tT7RmQonHc7Od9fNmDQ2TdaNro1RwYzi8tblnpBy3G2dUOo740ovz IKcRnORBcn/RZQ6SRcC8j0LlUQdT+Vs77xKutX5shBmMVfGmVPkQ5hPq//JU8= 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 :message-id:date:from:mime-version:to:subject:content-type; s= default; bh=xWPO9itDQWCnVw/efQgqjUGoA8k=; b=qlbfs7p07/rBKPyjFpPL zCrE3Kj5LefQg7qGY2x+7qGYjYmbH6FshbERB7UFdIdD+UNOrxgvXhNZRenEAVAV Elx/YopXMJPVkMZ5zbrdExlYX0MlF4uWPWHje9cLb6u8abc0zN1ulj/jpFKa43zm 3u7vcUE3pb3fLSe0nmXb85U= Received: (qmail 49783 invoked by alias); 20 Oct 2016 14:58:01 -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 49769 invoked by uid 89); 20 Oct 2016 14:58:00 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.2 required=5.0 tests=BAYES_00, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD autolearn=no version=3.3.2 spammy=do_something, *test_fptr_t, test_fptr_t, test_f 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, 20 Oct 2016 14:57:50 +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 DB2FDC16; Thu, 20 Oct 2016 07:57:47 -0700 (PDT) Received: from [10.2.207.77] (e100706-lin.cambridge.arm.com [10.2.207.77]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 8C7443F32C for ; Thu, 20 Oct 2016 07:57:47 -0700 (PDT) Message-ID: <5808DB6A.6070105@foss.arm.com> Date: Thu, 20 Oct 2016 15:57:46 +0100 From: Kyrill Tkachov User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0 MIME-Version: 1.0 To: GCC Patches Subject: [PATCH][ree] PR rtl-optimization/78038: Handle global register dataflow definitions in ree Hi all, In this PR we've got code like this: register struct test2_s *g __asm__("x28"); void do_something () { test_fptr (); struct test2_s *p1 = 0; *p1 = *g; } And we get an ICE in gcc/ree.c:655 in get_sub_rtx. The problem is when we try to process the defining insn of register x28 from the insn: (set (reg/f:DI 1 x1 [orig:74 g.1_2 ] [74]) (zero_extend:DI (reg/v:SI 28 x28 [ g ]))) The dataflow reports the insn setting x28 to be: (call_insn 8 7 10 2 (parallel [ (call (mem:DI (reg/f:DI 0 x0 [orig:77 test_fptr ] [77]) [0 *test_fptr.0_1 S8 A8]) (const_int 0 [0])) (use (const_int 0 [0])) (clobber (reg:DI 30 x30)) ]) "ree.c":14 41 {*call_reg} (expr_list:REG_CALL_DECL (nil) (nil)) (expr_list (clobber (reg:DI 17 x17)) (expr_list (clobber (reg:DI 16 x16)) (nil)))) which, as you can see, doesn't actually set x28. AFAICS the reason dataflow reports call_insn 8 as defining x28 is because x28 is a global register variable and that means that every function call is considered to define it. But the ree pass can't really use any of that. It only wants some SET RTL patterns to play with. One solution is to bail out at the ICE location, in get_sub_rtx, when no SETs are found inside the parallel. But I think we shouldn't be getting this far along anyway. So this patch prevents the call_insn from being recognised as a defining insn for x28 for the purposes of ree. It makes sure that if the register we're extending is a global register that all the insns in the def chain actually set it directly as determined by set_of from rtlanal.c. This should hopefully still allow ree to optimise extensions of global registers as long as they are combined with legitimate defining insns. Bootstrapped and tested on aarch64, arm, x86_64. Ok for trunk? Thanks, Kyrill 2016-10-20 Kyrylo Tkachov PR rtl-optimization/78038 * ree.c (get_defs): Return NULL if a defining insn for REG cannot be deduced to set REG through the RTL structure. (make_defs_and_copies_lists): Return false on a failing get_defs call. 2016-10-20 Kyrylo Tkachov PR rtl-optimization/78038 * gcc.target/aarch64/pr78038.c: New test. diff --git a/gcc/ree.c b/gcc/ree.c index 4ab2ad088c363caaaae8abaad375ec5a78bf13ea..374988e792e27fc342518e8e98af618bc595dbce 100644 --- a/gcc/ree.c +++ b/gcc/ree.c @@ -482,6 +482,14 @@ get_defs (rtx_insn *insn, rtx reg, vec *dest) return NULL; if (DF_REF_INSN_INFO (ref_link->ref) == NULL) return NULL; + /* As global regs are assumed to be defined at each function call + dataflow can report a call_insn as being a definition of REG. + But we can't do anything with that in this pass so proceed only + if the instruction really sets REG in a way that can be deduced + from the RTL structure. */ + if (global_regs[REGNO (reg)] + && !set_of (reg, DF_REF_INSN (ref_link->ref))) + return NULL; } if (dest) @@ -580,7 +588,7 @@ make_defs_and_copies_lists (rtx_insn *extend_insn, const_rtx set_pat, /* Initialize the work list. */ if (!get_defs (extend_insn, src_reg, &state->work_list)) - gcc_unreachable (); + return false; is_insn_visited = XCNEWVEC (bool, max_insn_uid); diff --git a/gcc/testsuite/gcc.target/aarch64/pr78038.c b/gcc/testsuite/gcc.target/aarch64/pr78038.c new file mode 100644 index 0000000000000000000000000000000000000000..76d97d3b0ad44cd75afa1e1e45434413421c5afa --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr78038.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +/* PR rtl-optimization/78038. + Make sure ree can gracefully handle extensions of the global + variable register after a call. */ + +typedef void (*test_fptr_t) (void); +void +test_f (void) +{ +} +test_fptr_t test_fptr = test_f; + +struct test2_s +{ + int f; +}; + +register struct test2_s *g __asm__("x28"); + +void +do_something () +{ + test_fptr (); + struct test2_s *p1 = 0; + *p1 = *g; +}