From patchwork Thu Nov 17 11:34:27 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 696089 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 3tKJvZ1G6Zz9syB for ; Thu, 17 Nov 2016 22:35:04 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="bG6I78tW"; dkim-atps=neutral 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=Z22YLk7bTWeM VdzEsQAMNG7FhALQKOpdrtSQ7YcopwLeO5HX9FinrzyDYdt3x/rC2yjOqE6FwUgz 5oVwqRRsBNBf7y5wSOT1nttpaAI0dFeosAc+bGGbjr6oQaz40U3bzKCwPF34m3qz bRA9kPwu445/dpe5aEMGMEnz+LrYU2Y= 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=f6soVw9jOzY9JkThYk LScMT/jRw=; b=bG6I78tWyPFUvsYBdY6t7Ok2josqAZc58dNRCk1+/YtmwRij4Z sTibHThJaHeHO2WjeeIIKrrNbkkvMdSOC48WKoBBflDcvivavE6CFGN03AXJ0Ji1 dFkWPO5O9bKqjU9DJ9ORwZO26jpsuVmA7tbuJV4fkI/F4IkBGICzEwbD8= Received: (qmail 20599 invoked by alias); 17 Nov 2016 11:34:44 -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 19953 invoked by uid 89); 17 Nov 2016 11:34:44 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.3 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=no version=3.3.2 spammy=H*MI:andrew, signextend, Hx-languages-length:6917, sign-extend X-HELO: mail-wm0-f47.google.com Received: from mail-wm0-f47.google.com (HELO mail-wm0-f47.google.com) (74.125.82.47) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 17 Nov 2016 11:34:33 +0000 Received: by mail-wm0-f47.google.com with SMTP id g23so304803246wme.1 for ; Thu, 17 Nov 2016 03:34:33 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=u87ryOyIWIrfzeLG+Bxl7R9wOxDoS4tEXBBYWW/xqWQ=; b=WjFKumH2UC0V9G1doFNoFpfHaqw3r+WP2GROVMLVwIoAkxStkGbvNplTN14S6FyEKv 2H45ilCnIfIKsWvS/4XJcb3wN4etB8qHwjrGkHA2I2Ahk0FyL7sh2tgDErKPgV8z2wD2 wDOZwtEspuk+sGYANmUgzy2ATDTMZIf0sBSPvbNcuPncXS35+SnwmC8Z9lVs2T05Cr1h 5DX4gfo/mc1au1XkAc15nj525k6sNHmjnUhG9cEMhDOPGo7l4lcWRyQ1sEuKt0CflxQE dKhNBrMKQ2B0PsF4+2b5di+1afZ5SvMzMpVVm1ggbYyp/+CI5ngJjDcjKR4qAuytTli3 i1vQ== X-Gm-Message-State: AKaTC01i99M1ZJzZL50J43WL/1l7KitIPmCQr7RLKJikLItMw3lE1BQPtTS4Qqvu/ukKbw== X-Received: by 10.28.158.148 with SMTP id h142mr3829024wme.59.1479382471709; Thu, 17 Nov 2016 03:34:31 -0800 (PST) Received: from localhost (host86-135-139-198.range86-135.btcentralplus.com. [86.135.139.198]) by smtp.gmail.com with ESMTPSA id jm6sm2777114wjb.27.2016.11.17.03.34.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 17 Nov 2016 03:34:30 -0800 (PST) From: Andrew Burgess To: gcc-patches@gcc.gnu.org Cc: noamca@mellanox.com, guybe@mellanox.com, Claudiu.Zissulescu@synopsys.com, Andrew Burgess Subject: [PATCH] arc/nps400: New peephole2 pattern allow more cmem loads Date: Thu, 17 Nov 2016 11:34:27 +0000 Message-Id: <1479382467-25790-1-git-send-email-andrew.burgess@embecosm.com> X-IsSubscribed: yes In the case where we access a single bit from a value and use this in a EQ/NE comparison, GCC will convert this into a sign-extend and GE/LT comparison. Normally this would be fine, however, if the value is in CMEM memory, then we don't have a sign-extending load available (using the special short CMEM load instructions), and instead we end up using a long form load with LIMM, which is less efficient. This peephole optimisation looks for the sign-extend followed by GE/LT pattern and converts this back into a load and EQ/NE comparison. gcc/ChangeLog: * config/arc/arc.md (cmem bit/sign-extend peephole2): New peephole to make better use of cmem loads in the case where a single bit is being accessed. * config/arc/predicates.md (ge_lt_comparison_operator): New predicate. gcc/testsuite/ChangeLog: * gcc.target/arc/cmem-bit-1.c: New file. * gcc.target/arc/cmem-bit-2.c: New file. * gcc.target/arc/cmem-bit-3.c: New file. * gcc.target/arc/cmem-bit-4.c: New file. --- gcc/ChangeLog | 8 ++++++ gcc/config/arc/arc.md | 43 +++++++++++++++++++++++++++++++ gcc/config/arc/predicates.md | 3 +++ gcc/testsuite/ChangeLog | 7 +++++ gcc/testsuite/gcc.target/arc/cmem-bit-1.c | 20 ++++++++++++++ gcc/testsuite/gcc.target/arc/cmem-bit-2.c | 20 ++++++++++++++ gcc/testsuite/gcc.target/arc/cmem-bit-3.c | 20 ++++++++++++++ gcc/testsuite/gcc.target/arc/cmem-bit-4.c | 20 ++++++++++++++ 8 files changed, 141 insertions(+) create mode 100644 gcc/testsuite/gcc.target/arc/cmem-bit-1.c create mode 100644 gcc/testsuite/gcc.target/arc/cmem-bit-2.c create mode 100644 gcc/testsuite/gcc.target/arc/cmem-bit-3.c create mode 100644 gcc/testsuite/gcc.target/arc/cmem-bit-4.c diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md index c494ca5..2d745cf 100644 --- a/gcc/config/arc/arc.md +++ b/gcc/config/arc/arc.md @@ -1465,6 +1465,49 @@ [(set_attr "type" "cmove,cmove") (set_attr "length" "4,8")]) +;; When there's a mask of a single bit, and then a compare to 0 or 1, +;; if the single bit is the sign bit, then GCC likes to convert this +;; into a sign extend and a compare less than, or greater to zero. +;; This is usually fine, except for the NXP400 where we have access to +;; a bit test instruction, along with a special short load instruction +;; (from CMEM), that doesn't support sign-extension on load. +;; +;; This peephole optimisation attempts to restore the use of bit-test +;; in those cases where it is useful to do so. +(define_peephole2 + [(set (match_operand:SI 0 "register_operand" "") + (sign_extend:SI + (match_operand:QI 1 "any_mem_operand" ""))) + (set (reg:CC_ZN CC_REG) + (compare:CC_ZN (match_dup 0) + (const_int 0))) + (set (pc) + (if_then_else (match_operator 2 "ge_lt_comparison_operator" + [(reg:CC_ZN CC_REG) (const_int 0)]) + (match_operand 3 "" "") + (match_operand 4 "" "")))] + "TARGET_NPS_CMEM + && cmem_address (XEXP (operands[1], 0), SImode) + && peep2_reg_dead_p (2, operands[0]) + && peep2_regno_dead_p (3, CC_REG)" + [(set (match_dup 0) + (zero_extend:SI + (match_dup 1))) + (set (reg:CC_ZN CC_REG) + (compare:CC_ZN (zero_extract:SI + (match_dup 0) + (const_int 1) + (const_int 7)) + (const_int 0))) + (set (pc) + (if_then_else (match_dup 2) + (match_dup 3) + (match_dup 4)))] + "if (GET_CODE (operands[2]) == GE) + operands[2] = gen_rtx_EQ (VOIDmode, gen_rtx_REG (CC_ZNmode, 61), const0_rtx); + else + operands[2] = gen_rtx_NE (VOIDmode, gen_rtx_REG (CC_ZNmode, 61), const0_rtx);") + ; Try to generate more short moves, and/or less limms, by substituting a ; conditional move with a conditional sub. (define_peephole2 diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md index cb75dbc..d8c9281 100644 --- a/gcc/config/arc/predicates.md +++ b/gcc/config/arc/predicates.md @@ -452,6 +452,9 @@ (define_predicate "equality_comparison_operator" (match_code "eq, ne")) +(define_predicate "ge_lt_comparison_operator" + (match_code "ge, lt")) + (define_predicate "brcc_nolimm_operator" (ior (match_test "REG_P (XEXP (op, 1))") (and (match_code "eq, ne, lt, ge, ltu, geu") diff --git a/gcc/testsuite/gcc.target/arc/cmem-bit-1.c b/gcc/testsuite/gcc.target/arc/cmem-bit-1.c new file mode 100644 index 0000000..d49ab5c --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/cmem-bit-1.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-mcpu=nps400 -mcmem -O2" } */ + +struct strange_bool +{ + unsigned char bool_bit :1; + unsigned char other_bits :7; +}; + +struct strange_bool a_strange_bool __attribute__((section(".cmem"))); + +extern void bar(); + +void foo() { + if (a_strange_bool.bool_bit) + bar(); +} + +/* { dg-final { scan-assembler "xldb r\[0-9\]+,\\\[@a_strange_bool\\\]" } } */ +/* { dg-final { scan-assembler "btst_s r\[0-9\]+,7" { target arceb-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/arc/cmem-bit-2.c b/gcc/testsuite/gcc.target/arc/cmem-bit-2.c new file mode 100644 index 0000000..45b49c6 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/cmem-bit-2.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-mcpu=nps400 -mcmem -O2" } */ + +struct strange_bool +{ + unsigned short bool_bit :1; + unsigned short other_bits :15; +}; + +struct strange_bool a_strange_bool __attribute__((section(".cmem"))); + +extern void bar(); + +void foo() { + if (a_strange_bool.bool_bit) + bar(); +} + +/* { dg-final { scan-assembler "xldb r\[0-9\]+,\\\[@a_strange_bool\\\]" } } */ +/* { dg-final { scan-assembler "btst_s r\[0-9\]+,7" { target arceb-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/arc/cmem-bit-3.c b/gcc/testsuite/gcc.target/arc/cmem-bit-3.c new file mode 100644 index 0000000..371ff2b --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/cmem-bit-3.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-mcpu=nps400 -mcmem -O2" } */ + +struct strange_bool +{ + unsigned int bool_bit :1; + unsigned int other_bits :31; +}; + +struct strange_bool a_strange_bool __attribute__((section(".cmem"))); + +extern void bar(); + +void foo() { + if (a_strange_bool.bool_bit) + bar(); +} + +/* { dg-final { scan-assembler "xldb r\[0-9\]+,\\\[@a_strange_bool\\\]" } } */ +/* { dg-final { scan-assembler "btst_s r\[0-9\]+,7" { target arceb-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/arc/cmem-bit-4.c b/gcc/testsuite/gcc.target/arc/cmem-bit-4.c new file mode 100644 index 0000000..a95c6ae --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/cmem-bit-4.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-mcpu=nps400 -mcmem -O2" } */ + +struct strange_bool +{ + unsigned long long bool_bit :1; + unsigned long long other_bits :61; +}; + +struct strange_bool a_strange_bool __attribute__((section(".cmem"))); + +extern void bar(); + +void foo() { + if (a_strange_bool.bool_bit) + bar(); +} + +/* { dg-final { scan-assembler "xldb r\[0-9\]+,\\\[@a_strange_bool\\\]" } } */ +/* { dg-final { scan-assembler "btst_s r\[0-9\]+,7" { target arceb-*-* } } } */