From patchwork Fri Oct 18 19:48:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Richard Earnshaw \(lists\)" X-Patchwork-Id: 176960 Delivered-To: patch@linaro.org Received: by 2002:ac9:3c86:0:0:0:0:0 with SMTP id w6csp1294784ocf; Fri, 18 Oct 2019 12:58:12 -0700 (PDT) X-Google-Smtp-Source: APXvYqxaX9aRCS83JP6rYHmvDhp5HaXPeu6qPqVlf5LPxpPktbEXKzSU+d6AIibpI2FSmSVrp3kS X-Received: by 2002:a17:906:58d:: with SMTP id 13mr10399548ejn.293.1571428692280; Fri, 18 Oct 2019 12:58:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1571428692; cv=none; d=google.com; s=arc-20160816; b=T174k0U4NUpXi58gheGcox3CeINqFPsozXfKaE7L6x9MPxfxHif1DVYHuxnIrvCQhr O9QBP9zGWNuWjQ9YqeL8kzmm6wD0ut6mln9yVxWQa4I8hscUV2UuzHAZ/aG80XoUHbiX qvBbRzKfzvDF4423N4YqScOd7fKzjc9azJMd9i3ZRp1PGxXvMPceBwq6ABSh+rHMyVZH Ts+xUvyKD+s63agL+wV1UOCLxuf7aEynKOJe3UKDenJhO4Dg+ts72maDBgzG2kEtFJ7a apGt7yhdjQ+xeIJIqOJ55fVIFfPhRXCTHB3evvX9wBG96XAbsg0FIF5ApIF4h8dK7boe ZwSQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:delivered-to:sender:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature; bh=2e3NDw4idmNszCbGNYRg5P17rrWPFyqCBfb2k83DxO8=; b=B+EEqt1nhlIuR/xQrlbQrObCUdC3xOgJSH1RnKrdnbmixe3Ao+WL1MQ3YAMq+f3QI9 loCex97L4KLxuiBR8nd88YG5D5ZLLkeagZOxvlNiiAcRI4OdyciPW3Paj2QWwXmWu29P p+2Jq+gaxBtTc3FIFCHz5XmjeIBRek0+W2G0rihTMNCdrEu7G7vuBrBvMo7Rq7Db3W0I SMXZhjwnLAwfnN0sU27pHPOu+wbU4SUwzV8jbXkkwV1uLRFygysId0o/kcjEKc2MdwpJ mm103oZYrYOCWdf+Gtxbzg47EA7kFbPFKQ9oRv3Y6JZc54BqbJmqKC6rlzKswF5x6FNP Vu6Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=fLfBoHPg; spf=pass (google.com: domain of gcc-patches-return-511326-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="gcc-patches-return-511326-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 d15si4543602edq.430.2019.10.18.12.58.11 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 18 Oct 2019 12:58:12 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-511326-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=fLfBoHPg; spf=pass (google.com: domain of gcc-patches-return-511326-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="gcc-patches-return-511326-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:from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type; q=dns; s=default; b=SlGzh8WWXfDjgwNM aSBanO6O01c0AQdLc5cGxZ/31FCD+EyoTTbq5k3fS1lw3x4X0MWwfrhdPYN0MW7M IEewsM7zGh3Wl8VIAK/BDCZJb61mc7EBnmh2PNnWu83q6EwguQ0P14F3z5vKtJKk lcfwSsjDJ2gKYRt8Yqd9cf6cd10= 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:in-reply-to:references :mime-version:content-type; s=default; bh=oCrdpJgGcjOkNkU/BKJxMC FSfd0=; b=fLfBoHPgvfeKV8i/VD+VW6quOJn3H1lEQ0XiSntXOvn6ui5+Ru+Htd kpz2B2TXK69/DrE9OQwvhtNCQg3cRb5v22AvQ8houKIo67czKBIge4WgbSKi8t7c mX4W623sE1dD9tVTxAGUdjsaJXNUyJaaep4caDwPi/AUU5LHHX56E= Received: (qmail 114988 invoked by alias); 18 Oct 2019 19:55:45 -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 112944 invoked by uid 89); 18 Oct 2019 19:55:40 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.8 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_FAIL autolearn=ham version=3.3.1 spammy=leu, transforming X-HELO: eggs.gnu.org Received: from eggs.gnu.org (HELO eggs.gnu.org) (209.51.188.92) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 18 Oct 2019 19:55:39 +0000 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iLYLS-000559-BL for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:31 -0400 Received: from [217.140.110.172] (port=42754 helo=foss.arm.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1iLYLS-00054Y-3S for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:30 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id B9EF016F3; Fri, 18 Oct 2019 12:49:22 -0700 (PDT) Received: from eagle.buzzard.freeserve.co.uk (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 474D43F6C4; Fri, 18 Oct 2019 12:49:22 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 15/29] [arm] Improve handling of DImode comparisions against constants. Date: Fri, 18 Oct 2019 20:48:46 +0100 Message-Id: <20191018194900.34795-16-Richard.Earnshaw@arm.com> In-Reply-To: <20191018194900.34795-1-Richard.Earnshaw@arm.com> References: <20191018194900.34795-1-Richard.Earnshaw@arm.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 217.140.110.172 In almost all cases it is better to handle inequality handling against constants by transforming comparisons of the form (reg const) into (reg (const+1)). However, there are many cases that we could handle but currently failed to do so because we forced the constant into a register too early in the pattern expansion. To permit this to be done we need to defer forcing the constant into a register until after we've had the chance to do the transform - in some cases that may even mean that we no-longer need to force the constant into a register at all. For example, on Arm, the case: _Bool f8 (unsigned long long a) { return a > 0xffffffff; } previously compiled to mov r3, #0 cmp r1, r3 mvn r2, #0 cmpeq r0, r2 movhi r0, #1 movls r0, #0 bx lr But now compiles to cmp r1, #1 cmpeq r0, #0 movcs r0, #1 movcc r0, #0 bx lr Which although not yet completely optimal, is certainly better than previously. * config/arm/arm.md (cbranchdi4): Accept reg_or_int_operand for operand 2. (cstoredi4): Similarly, but for operand 3. * config/arm/arm.c (arm_canoncialize_comparison): Allow canonicalization of unsigned compares with a constant on Arm. Prefer using const+1 and adjusting the comparison over swapping the operands whenever the original constant was not valid. (arm_gen_dicompare_reg): If Y is not a valid operand, force it to a register here. (arm_validize_comparison): Do not force invalid DImode operands to registers here. --- gcc/config/arm/arm.c | 37 +++++++++++++++++++++++-------------- gcc/config/arm/arm.md | 4 ++-- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 64367b42332..ddfe4335169 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -5372,15 +5372,16 @@ arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1, maxval = (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (mode) - 1)) - 1; - /* For DImode, we have GE/LT/GEU/LTU comparisons. In ARM mode - we can also use cmp/cmpeq for GTU/LEU. GT/LE must be either - reversed or (for constant OP1) adjusted to GE/LT. Similarly - for GTU/LEU in Thumb mode. */ + /* For DImode, we have GE/LT/GEU/LTU comparisons (with cmp/sbc). In + ARM mode we can also use cmp/cmpeq for GTU/LEU. GT/LE must be + either reversed or (for constant OP1) adjusted to GE/LT. + Similarly for GTU/LEU in Thumb mode. */ if (mode == DImode) { if (*code == GT || *code == LE - || (!TARGET_ARM && (*code == GTU || *code == LEU))) + || ((!TARGET_ARM || CONST_INT_P (*op1)) + && (*code == GTU || *code == LEU))) { /* Missing comparison. First try to use an available comparison. */ @@ -5392,23 +5393,27 @@ arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1, case GT: case LE: if (i != maxval - && arm_const_double_by_immediates (GEN_INT (i + 1))) + && (!arm_const_double_by_immediates (*op1) + || arm_const_double_by_immediates (GEN_INT (i + 1)))) { *op1 = GEN_INT (i + 1); *code = *code == GT ? GE : LT; return; } break; + case GTU: case LEU: if (i != ~((unsigned HOST_WIDE_INT) 0) - && arm_const_double_by_immediates (GEN_INT (i + 1))) + && (!arm_const_double_by_immediates (*op1) + || arm_const_double_by_immediates (GEN_INT (i + 1)))) { *op1 = GEN_INT (i + 1); *code = *code == GTU ? GEU : LTU; return; } break; + default: gcc_unreachable (); } @@ -15436,7 +15441,7 @@ arm_gen_dicompare_reg (rtx_code code, rtx x, rtx y, rtx scratch) scratch = gen_reg_rtx (SImode); if (ylo == const0_rtx) { - yhi = GEN_INT (-INTVAL(yhi)); + yhi = gen_int_mode (-INTVAL (yhi), SImode); if (!arm_add_operand (yhi, SImode)) yhi = force_reg (SImode, yhi); emit_insn (gen_addsi3 (scratch, xhi, yhi)); @@ -15445,7 +15450,7 @@ arm_gen_dicompare_reg (rtx_code code, rtx x, rtx y, rtx scratch) else { gcc_assert (yhi == const0_rtx); - ylo = GEN_INT (-INTVAL(ylo)); + ylo = gen_int_mode (-INTVAL (ylo), SImode); if (!arm_add_operand (ylo, SImode)) ylo = force_reg (SImode, ylo); emit_insn (gen_addsi3 (scratch, xlo, ylo)); @@ -15458,6 +15463,8 @@ arm_gen_dicompare_reg (rtx_code code, rtx x, rtx y, rtx scratch) x = gen_rtx_IOR (SImode, gen_lowpart (SImode, x), gen_highpart (SImode, x)); } + else if (!cmpdi_operand (y, mode)) + y = force_reg (DImode, y); /* A scratch register is required. */ if (reload_completed) @@ -15470,7 +15477,12 @@ arm_gen_dicompare_reg (rtx_code code, rtx x, rtx y, rtx scratch) emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, clobber))); } else - emit_set_insn (cc_reg, gen_rtx_COMPARE (mode, x, y)); + { + if (!cmpdi_operand (y, mode)) + y = force_reg (DImode, y); + + emit_set_insn (cc_reg, gen_rtx_COMPARE (mode, x, y)); + } return cc_reg; } @@ -30479,10 +30491,7 @@ arm_validize_comparison (rtx *comparison, rtx * op1, rtx * op2) return true; case E_DImode: - if (!cmpdi_operand (*op1, mode)) - *op1 = force_reg (mode, *op1); - if (!cmpdi_operand (*op2, mode)) - *op2 = force_reg (mode, *op2); + /* gen_compare_reg() will sort out any invalid operands. */ return true; case E_HFmode: diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index a6b0c196c58..9d8b137651f 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -6397,7 +6397,7 @@ (define_expand "cbranchdi4" [(set (pc) (if_then_else (match_operator 0 "expandable_comparison_operator" [(match_operand:DI 1 "s_register_operand") - (match_operand:DI 2 "cmpdi_operand")]) + (match_operand:DI 2 "reg_or_int_operand")]) (label_ref (match_operand 3 "" "")) (pc)))] "TARGET_32BIT" @@ -6862,7 +6862,7 @@ (define_expand "cstoredi4" [(set (match_operand:SI 0 "s_register_operand") (match_operator:SI 1 "expandable_comparison_operator" [(match_operand:DI 2 "s_register_operand") - (match_operand:DI 3 "cmpdi_operand")]))] + (match_operand:DI 3 "reg_or_int_operand")]))] "TARGET_32BIT" "{ if (!arm_validize_comparison (&operands[1],