From patchwork Thu Oct 19 13:20:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Richard Earnshaw \(lists\)" X-Patchwork-Id: 116396 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp491639qgn; Thu, 19 Oct 2017 06:20:47 -0700 (PDT) X-Google-Smtp-Source: ABhQp+Qzm773ZAXMykfyw667wws/e8aMZBZWi/iDpwNBwSb7B42qbEtxkbXuwvlr6jKtvUIF1vNw X-Received: by 10.159.218.9 with SMTP id v9mr1488222plp.92.1508419247887; Thu, 19 Oct 2017 06:20:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1508419247; cv=none; d=google.com; s=arc-20160816; b=qnByxvJv7YyPlkVQQQ9O0JhmflSecqc4Hg9YcEz3pTIbMEKXrmN4xgllHlNDs5BEtV NTjw6NX3FYRHVj84HMezZ7IRTysIR2GnR3x0Mh7SYL4GqfQA+SvfrawkdpUNqjAhbDxE YI4VHcFGqEFUdRqBowxQEdSg6UwSXNI8pDqnvY3r1azoUSVQE4wjno0pg8Cwpo3nAlks /qD0k6Vk4ayX6is0a0yWEPPbPSmadGx8ZwzIa9DyXU+v3oRhcCtllt6gAYp7bZkMgGq5 TctpLpJ8GW7MdHd7SGcCrTYniISsfBLkZ+dPCy9PZvOGp64V/Rp+e7Fm+DSk/HPppFmd +oSg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:user-agent:date:message-id:subject:from:to :delivered-to:sender:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=axNUhogyv4jYe3vlqFmt5D4cuGIJBEmhiQLvFVoUufU=; b=geWPMj10Ul/OkryAaIEroc1ohRXMi29uPM+LomCAzqrOgsaYuLU5RYnqXu24L74fDl m6eIP7RD0Re2qUjiFSUHVyJx4mMuxm8r57IGdoAUeryx4WsBax4ojTGLzczDq6bFJfzy LkDy76t/X8DIUeHlZ6h4VRZJJZUbSVJSeZuYvhTdvnAaMfiupf3GwZTyR++zapBFDPGp hywcX2vRIj9LC6NBBXVZ8n0ERoG8MqVVCF+zj92w+4+yZsS3HzHNmd6KdZKQaXSvwolE /L6N9HWCef5b9PWmrfQNt94rArVDtT+/+UffSADC7EFPf/HayfPwt9nC5Xc+crUWp5yf ks2Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=efRNFnRf; spf=pass (google.com: domain of gcc-patches-return-464535-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-464535-patch=linaro.org@gcc.gnu.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id p2si3306602pfd.273.2017.10.19.06.20.47 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 19 Oct 2017 06:20:47 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-464535-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 header.s=default header.b=efRNFnRf; spf=pass (google.com: domain of gcc-patches-return-464535-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-464535-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=kWrm4aKSl4zcnR57IX1rKv1I75qnIe9kD57HYpGAc7mmR4xyQ/ nTak5aQzh8trNWLLRjtwyjWYrOzuyAEnu8RUmD4EmQwqfjIzHlDGqrMHYufVnReE LmmuZmZNA8Hlgss/5WXe2H7OJoE7SCybxOzmW/u4TvrJRQ2lLI5db198s= 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=e+VqQnhg2+VePOMHL0sOwSTI7KI=; b=efRNFnRf1Dkz6syVWhu4 GUHGo3lKpY8Vtzo3nD69RReXS/BaVWueJJUzcd48Wl0HOcTVF4J6avCiycGCjVKQ UgE49q2jqGh1mNnjuDItbzkxnYzdRL1WeFIZxz3xhR9X0ePqFanTEnUCHyZ2Xbnt NC1R21U4w+AkbW3X79Ahyg4= Received: (qmail 45098 invoked by alias); 19 Oct 2017 13:20:09 -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 45020 invoked by uid 89); 19 Oct 2017 13:20:09 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: foss.arm.com Received: from usa-sjc-mx-foss1.foss.arm.com (HELO foss.arm.com) (217.140.101.70) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 19 Oct 2017 13:20:06 +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 EA053F; Thu, 19 Oct 2017 06:20:04 -0700 (PDT) Received: from e105689-lin.cambridge.arm.com (e105689-lin.cambridge.arm.com [10.2.207.32]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 73F713F3E1; Thu, 19 Oct 2017 06:20:04 -0700 (PDT) To: gcc-patches From: "Richard Earnshaw (lists)" Subject: [ARM] PR 82445 - suppress 32-bit aligned ldrd/strd peepholing with -mno-unaligned-access Message-ID: <1ebeb40f-1c21-adf4-59c8-e4f86abd09bb@arm.com> Date: Thu, 19 Oct 2017 14:20:03 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0 MIME-Version: 1.0 Peephole patterns exist in the arm backend to spot load/store operations to adjacent memory operations in order to convert them into ldrd/strd instructions. However, when we have strict alignment enforced, then we can only do this if the accesses are known to be 64-bit aligned; this is unlikely to be the case for most loads. The patch adds some alignment checking to the code that validates the addresses for use in the peephole patterns. This should also fix incorrect generation of ldrd/strd with unaligned accesses that could previously have occurred on ARMv5e where all such operations must be 64-bit aligned. I've added some new tests as well. In doing so I discovered that the ldrd/strd peephole tests could never fail since they would match the source file name in the scanned assembly as well as any instructions of the intended type. I've fixed those by tightening the scan results slightly. gcc: PR target/82445 * config/arm/arm.c (align_ok_ldrd_strd): New function. (mem_ok_for_ldrd_strd): New parameter align. Extract the alignment of the mem into it. (gen_operands_ldrd_strd): Validate the alignment of the accesses. testsuite: PR target/82445 * gcc.target/arm/peep-ldrd-1.c: Tighten test scan pattern. * gcc.target/arm/peep-strd-1.c: Likewise. * gcc.target/arm/peep-ldrd-2.c: New test. * gcc.target/arm/peep-strd-2.c: New test. Committed to all active branches (trunk, 6 & 7). diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 622218c..879be49 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -15288,12 +15288,23 @@ operands_ok_ldrd_strd (rtx rt, rtx rt2, rtx rn, HOST_WIDE_INT offset, return true; } +/* Return true if a 64-bit access with alignment ALIGN and with a + constant offset OFFSET from the base pointer is permitted on this + architecture. */ +static bool +align_ok_ldrd_strd (HOST_WIDE_INT align, HOST_WIDE_INT offset) +{ + return (unaligned_access + ? (align >= BITS_PER_WORD && (offset & 3) == 0) + : (align >= 2 * BITS_PER_WORD && (offset & 7) == 0)); +} + /* Helper for gen_operands_ldrd_strd. Returns true iff the memory operand MEM's address contains an immediate offset from the base - register and has no side effects, in which case it sets BASE and - OFFSET accordingly. */ + register and has no side effects, in which case it sets BASE, + OFFSET and ALIGN accordingly. */ static bool -mem_ok_for_ldrd_strd (rtx mem, rtx *base, rtx *offset) +mem_ok_for_ldrd_strd (rtx mem, rtx *base, rtx *offset, HOST_WIDE_INT *align) { rtx addr; @@ -15312,6 +15323,7 @@ mem_ok_for_ldrd_strd (rtx mem, rtx *base, rtx *offset) gcc_assert (MEM_P (mem)); *offset = const0_rtx; + *align = MEM_ALIGN (mem); addr = XEXP (mem, 0); @@ -15352,7 +15364,7 @@ gen_operands_ldrd_strd (rtx *operands, bool load, bool const_store, bool commute) { int nops = 2; - HOST_WIDE_INT offsets[2], offset; + HOST_WIDE_INT offsets[2], offset, align[2]; rtx base = NULL_RTX; rtx cur_base, cur_offset, tmp; int i, gap; @@ -15364,7 +15376,8 @@ gen_operands_ldrd_strd (rtx *operands, bool load, registers, and the corresponding memory offsets. */ for (i = 0; i < nops; i++) { - if (!mem_ok_for_ldrd_strd (operands[nops+i], &cur_base, &cur_offset)) + if (!mem_ok_for_ldrd_strd (operands[nops+i], &cur_base, &cur_offset, + &align[i])) return false; if (i == 0) @@ -15478,6 +15491,7 @@ gen_operands_ldrd_strd (rtx *operands, bool load, /* Swap the instructions such that lower memory is accessed first. */ std::swap (operands[0], operands[1]); std::swap (operands[2], operands[3]); + std::swap (align[0], align[1]); if (const_store) std::swap (operands[4], operands[5]); } @@ -15491,6 +15505,9 @@ gen_operands_ldrd_strd (rtx *operands, bool load, if (gap != 4) return false; + if (!align_ok_ldrd_strd (align[0], offset)) + return false; + /* Make sure we generate legal instructions. */ if (operands_ok_ldrd_strd (operands[0], operands[1], base, offset, false, load)) diff --git a/gcc/testsuite/gcc.target/arm/peep-ldrd-1.c b/gcc/testsuite/gcc.target/arm/peep-ldrd-1.c index eb2b86e..d49eff6 100644 --- a/gcc/testsuite/gcc.target/arm/peep-ldrd-1.c +++ b/gcc/testsuite/gcc.target/arm/peep-ldrd-1.c @@ -8,4 +8,4 @@ int foo(int a, int b, int* p, int *q) *p = a; return a; } -/* { dg-final { scan-assembler "ldrd" } } */ +/* { dg-final { scan-assembler "ldrd\\t" } } */ diff --git a/gcc/testsuite/gcc.target/arm/peep-ldrd-2.c b/gcc/testsuite/gcc.target/arm/peep-ldrd-2.c new file mode 100644 index 0000000..6822c2b --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/peep-ldrd-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_prefer_ldrd_strd } */ +/* { dg-options "-O2 -mno-unaligned-access" } */ +int foo(int a, int b, int* p, int *q) +{ + a = p[2] + p[3]; + *q = a; + *p = a; + return a; +} +/* { dg-final { scan-assembler-not "ldrd\\t" } } */ diff --git a/gcc/testsuite/gcc.target/arm/peep-strd-1.c b/gcc/testsuite/gcc.target/arm/peep-strd-1.c index bd33076..fe1beac 100644 --- a/gcc/testsuite/gcc.target/arm/peep-strd-1.c +++ b/gcc/testsuite/gcc.target/arm/peep-strd-1.c @@ -6,4 +6,4 @@ void foo(int a, int b, int* p) p[2] = a; p[3] = b; } -/* { dg-final { scan-assembler "strd" } } */ +/* { dg-final { scan-assembler "strd\\t" } } */ diff --git a/gcc/testsuite/gcc.target/arm/peep-strd-2.c b/gcc/testsuite/gcc.target/arm/peep-strd-2.c new file mode 100644 index 0000000..bfc5ebe --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/peep-strd-2.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_prefer_ldrd_strd } */ +/* { dg-options "-O2 -mno-unaligned-access" } */ +void foo(int a, int b, int* p) +{ + p[2] = a; + p[3] = b; +} +/* { dg-final { scan-assembler-not "strd\\t" } } */