From patchwork Wed Nov 30 16:47:44 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kyrill Tkachov X-Patchwork-Id: 85896 Delivered-To: patch@linaro.org Received: by 10.140.20.101 with SMTP id 92csp312247qgi; Wed, 30 Nov 2016 08:48:12 -0800 (PST) X-Received: by 10.99.209.5 with SMTP id k5mr61715353pgg.145.1480524492416; Wed, 30 Nov 2016 08:48:12 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id s3si36606827plb.40.2016.11.30.08.48.12 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 30 Nov 2016 08:48:12 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-443092-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-443092-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-443092-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:cc:subject:content-type; q=dns; s=default; b=sW3JQXlG5T7w97DdP5mvluCh87Y6W5yUEH65ISGEfBB Dqtj1CTTY5XcyFnzUPd0oQDb4RGHeHj5wJLVxVE3M6J4bDq3RQlbkatBLoeDyObA WcWfvhW8+qAhD8x6ZStCIEhh764AKZsE5V24Jvp0iSidwfJtTRMviBuUspDigh/M = 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:cc:subject:content-type; s=default; bh=+S9DsytOvRWHGF91NDT9Pde82Z8=; b=Bmx3b3l9GvyCa8VZi 03S175XpYHb3R3QsapykqdNHh/dz6ynGawsvz3rKsaP/nrz8MzTCCVe4h8ozhlcH WTtDAfR7oFsggVIN2KZ2kdxe05Hjtu4PCIa1JoAbzZEzHRZK9WD3Ify7D8x82Uim 2EldP+83O8AGDz2cDtAA9MUE4w= Received: (qmail 65433 invoked by alias); 30 Nov 2016 16:47:59 -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 65420 invoked by uid 89); 30 Nov 2016 16:47:58 -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=restrict, 20161130 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; Wed, 30 Nov 2016 16:47:48 +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 992FAAD7; Wed, 30 Nov 2016 08:47:46 -0800 (PST) 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 0470A3F445; Wed, 30 Nov 2016 08:47:45 -0800 (PST) Message-ID: <583F02B0.3030406@foss.arm.com> Date: Wed, 30 Nov 2016 16:47:44 +0000 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 CC: Ramana Radhakrishnan , Richard Earnshaw Subject: [PATCH][ARM] PR target/71436: Restrict *load_multiple pattern till after LRA Hi all, In this awkward ICE we have a *load_multiple pattern that is being transformed in reload from: (insn 55 67 151 3 (parallel [ (set (reg:SI 0 r0) (mem/u/c:SI (reg/f:SI 147) [2 c+0 S4 A32])) (set (reg:SI 158 [ c+4 ]) (mem/u/c:SI (plus:SI (reg/f:SI 147) (const_int 4 [0x4])) [2 c+4 S4 A32])) ]) arm-crash.c:25 393 {*load_multiple} (expr_list:REG_UNUSED (reg:SI 0 r0) (nil))) into the invalid: (insn 55 67 70 3 (parallel [ (set (reg:SI 0 r0) (mem/u/c:SI (reg/f:SI 5 r5 [147]) [2 c+0 S4 A32])) (set (mem/c:SI (plus:SI (reg/f:SI 102 sfp) (const_int -4 [0xfffffffffffffffc])) [4 %sfp+-12 S4 A32]) (mem/u/c:SI (plus:SI (reg/f:SI 5 r5 [147]) (const_int 4 [0x4])) [2 c+4 S4 A32])) ]) arm-crash.c:25 393 {*load_multiple} (nil)) The operands of *load_multiple are not validated through constraints like LRA is used to, but rather through a match_parallel predicate which ends up calling ldm_stm_operation_p to validate the multiple sets. But this means that LRA cannot reason about the constraints properly. This two-regiseter load should not have used *load_multiple anyway, it should have used *ldm2_ from ldmstm.md and indeed it did until the loop2_invariant pass which copied the ldm2_ pattern: (insn 27 23 28 4 (parallel [ (set (reg:SI 0 r0) (mem/u/c:SI (reg/f:SI 147) [2 c+0 S4 A32])) (set (reg:SI 1 r1) (mem/u/c:SI (plus:SI (reg/f:SI 147) (const_int 4 [0x4])) [2 c+4 S4 A32])) ]) "ldm.c":25 385 {*ldm2_} (nil)) into: (insn 55 19 67 3 (parallel [ (set (reg:SI 0 r0) (mem/u/c:SI (reg/f:SI 147) [2 c+0 S4 A32])) (set (reg:SI 158) (mem/u/c:SI (plus:SI (reg/f:SI 147) (const_int 4 [0x4])) [2 c+4 S4 A32])) ]) "ldm.c":25 404 {*load_multiple} (expr_list:REG_UNUSED (reg:SI 0 r0) (nil))) Note that it now got recognised as load_multiple because the second register is not a hard register but the pseudo 158. In any case, the solution suggested in the PR (and I agree with it) is to restrict *load_multiple to after reload. The similar pattern *load_multiple_with_writeback also has a similar condition and the comment above *load_multiple says that it's used to generate epilogues, which is done after reload anyway. For pre-reload load-multiples the patterns in ldmstm.md should do just fine. Bootstrapped and tested on arm-none-linux-gnueabihf. Ok for trunk? Thanks, Kyrill 2016-11-30 Kyrylo Tkachov PR target/71436 * config/arm/arm.md (*load_multiple): Add reload_completed to matching condition. 2016-11-30 Kyrylo Tkachov PR target/71436 * gcc.c-torture/compile/pr71436.c: New test. commit 996d28e2353badd1b29ef000f94d40c7dab9010f Author: Kyrylo Tkachov Date: Tue Nov 29 15:07:30 2016 +0000 [ARM] Restrict *load_multiple pattern till after LRA diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 74c44f3..22d2a84 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -11807,12 +11807,15 @@ (define_insn "" ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers ;; large lists without explicit writeback generated for APCS_FRAME epilogue. +;; The operands are validated through the load_multiple_operation +;; match_parallel predicate rather than through constraints so enable it only +;; after reload. (define_insn "*load_multiple" [(match_parallel 0 "load_multiple_operation" [(set (match_operand:SI 2 "s_register_operand" "=rk") (mem:SI (match_operand:SI 1 "s_register_operand" "rk"))) ])] - "TARGET_32BIT" + "TARGET_32BIT && reload_completed" "* { arm_output_multireg_pop (operands, /*return_pc=*/false, diff --git a/gcc/testsuite/gcc.c-torture/compile/pr71436.c b/gcc/testsuite/gcc.c-torture/compile/pr71436.c new file mode 100644 index 0000000..ab08d5d --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr71436.c @@ -0,0 +1,35 @@ +/* PR target/71436. */ + +#pragma pack(1) +struct S0 +{ + volatile int f0; + short f2; +}; + +void foo (struct S0 *); +int a, d; +static struct S0 b[5]; +static struct S0 c; +void fn1 (); +void +main () +{ + { + struct S0 e; + for (; d; fn1 ()) + { + { + a = 3; + for (; a >= 0; a -= 1) + { + { + e = c; + } + b[a] = e; + } + } + } + } + foo (b); +}