From patchwork Fri Oct 18 19:48:57 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: 176961 Delivered-To: patch@linaro.org Received: by 2002:ac9:3c86:0:0:0:0:0 with SMTP id w6csp1294978ocf; Fri, 18 Oct 2019 12:58:24 -0700 (PDT) X-Google-Smtp-Source: APXvYqwBOG+Y/3mYsqLi6Wc5mhnQacy56yVrCXSZwJ7wQm7BXywcF1e3tD1vda/hO40l/AV9YYuK X-Received: by 2002:a17:906:858d:: with SMTP id v13mr881257ejx.61.1571428704626; Fri, 18 Oct 2019 12:58:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1571428704; cv=none; d=google.com; s=arc-20160816; b=yLzx/FuoxEZBpYjDBFFNPggX0z97ZZEwVyrlUVpNvdDO5SKko9Tv8V8wszfQ6epHNj 9IDQXO5uyf67Io/UJ6rrarKWgiJQFxq57AWvLXYoIVaBO3MnJAwL2EyI40Vsl1yKwS2r SDSpE5su2YuR1IXNLKwcfticqnP0cMxS7jFvjXVkd0l1yq3oOscXqVP/P0PUSDFVZzYH Q1WrruqMDMMVYOfAOWQ0P6OoJTMfBm7gNjofQ+D42hm0XqgS2DbMlRNt5EGnN3yyQyLk OaBpZU1KmmN70War2hnVkM4YTKRiUDceUnVE7nqISeLdhLx2iEFf60owEDeILh9lsxRp ytuw== 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=YDcZc9qX8PUqG7MatLyFXIsnrhOm870YhB2FcAyyRKU=; b=0KyvTdXUXhAfcT8Mq7oQiKKSrpmhFqqTsw9L28vXcM+09V1jfwBoGsibAdByZfEv52 llVBWVHDoHckmvi1/Sa7N1jyO//0Pyytbe8yOisI71b/H5m1DCRWF4mI2PKadXZ8VBFM j3gCv81ICMt2pXJY6qfUzRy4dv0bz4JqtcYI3tN+7DFH42Ap4fNc1tBS6lEa8Kya2KtC C6ql/ujKaEYOrN4hhQ6DDAZzUU4ad48jSTobOm2T+AbGwv1sZ1fq2tHERBcCSAlm56+y aFKNG70/8LkX7rIZYSW66V7iUxPY8clUkIyS0JU+OweU8h+Q+hcIdzc2sgKKr5k3DBLB mF+Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=IGVkJbwO; spf=pass (google.com: domain of gcc-patches-return-511327-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="gcc-patches-return-511327-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 gg17si3790018ejb.294.2019.10.18.12.58.23 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 18 Oct 2019 12:58:24 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-511327-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=IGVkJbwO; spf=pass (google.com: domain of gcc-patches-return-511327-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="gcc-patches-return-511327-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=ZEAIH1/3fKDi/Wzl AEVAC26PaUUBpIiA1irK7re833ilkhmk+PS+IEGmvcSuFR1vHnBPY9naOa9GoWJO WFu4AquFQqnpea2e+qzOin2+IOcG2hIvVBEvX5XvG6ln7xY4iCBLXF79Fj4IJ96l ylfaV+aIEY9MY0/kYhD01+XXFEI= 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=nqrpwAQIEjEh6jH5cqItgV 6ZcKE=; b=IGVkJbwON9gMpv8ayAfCWU5OGFzMe2CBI4CN4rGyzmTSK8mBeXhVyH 4AYMs/K4BN/+u9UqG7WEN+2dtzhesQL0D1u/ioaoB0TW5jpxmgW1vOtmXEyI7Xb1 D5VldePBnQ2X78Wm6jDt/jA8GcCy8IYPMdKMVWRGSm1l24KSjjzVs= Received: (qmail 115030 invoked by alias); 18 Oct 2019 19:55:46 -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 113974 invoked by uid 89); 18 Oct 2019 19:55:42 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-19.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3 autolearn=ham version=3.3.1 spammy=rrr, r, r, r 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:41 +0000 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iLYLS-00054h-29 for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:31 -0400 Received: from [217.140.110.172] (port=42740 helo=foss.arm.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1iLYLR-00053X-R2 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 51DCE1045; Fri, 18 Oct 2019 12:49:30 -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 D38E83F6C4; Fri, 18 Oct 2019 12:49:29 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 26/29] [arm] Improve constant handling for subvsi4. Date: Fri, 18 Oct 2019 20:48:57 +0100 Message-Id: <20191018194900.34795-27-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 This patch addresses constant handling in subvsi4. Either operand may be a constant. If the second input (operand[2]) is a constant, then we can canonicalize this into an addition form, providing we take care of the INT_MIN case. In that case the negation has to handle the fact that -INT_MIN is still INT_MIN and we need to ensure that a subtract operation is performed rather than an addition. The remaining cases are largely duals of the usubvsi4 expansion. This patch also fixes a technical correctness bug in the old expansion, where we did not realy describe the test for overflow in the RTL. We seem to have got away with that, however... * config/arm/arm.md (subv4): Delete. (subvdi4): New expander pattern. (subvsi4): Likewise. Handle some immediate values. (subvsi3_intmin): New insn pattern. (subvsi3): Likewise. (subvsi3_imm1): Likewise. * config/arm/arm.c (select_cc_mode): Also allow minus for CC_V idioms. --- gcc/config/arm/arm.c | 5 ++- gcc/config/arm/arm.md | 96 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 94 insertions(+), 7 deletions(-) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index c9abbb0f91d..d5ffd2133a9 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -15413,11 +15413,12 @@ arm_select_cc_mode (enum rtx_code op, rtx x, rtx y) if (GET_MODE (x) == DImode && (op == EQ || op == NE) - && GET_CODE (x) == PLUS + && (GET_CODE (x) == PLUS + || GET_CODE (x) == MINUS) && (GET_CODE (XEXP (x, 0)) == SIGN_EXTEND || GET_CODE (XEXP (x, 1)) == SIGN_EXTEND) && GET_CODE (y) == SIGN_EXTEND - && GET_CODE (XEXP (y, 0)) == PLUS) + && GET_CODE (XEXP (y, 0)) == GET_CODE (x)) return CC_Vmode; if (GET_MODE_CLASS (GET_MODE (x)) == MODE_CC) diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 92f1823cdfa..05b735cfccd 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -957,6 +957,22 @@ (define_insn "*addsi3_compareV_reg_nosum" (set_attr "type" "alus_sreg")] ) +(define_insn "subvsi3_intmin" + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (plus:DI + (sign_extend:DI + (match_operand:SI 1 "register_operand" "r")) + (const_int 2147483648)) + (sign_extend:DI (plus:SI (match_dup 1) (const_int -2147483648))))) + (set (match_operand:SI 0 "register_operand" "=r") + (plus:SI (match_dup 1) (const_int -2147483648)))] + "TARGET_32BIT" + "subs%?\\t%0, %1, #-2147483648" + [(set_attr "conds" "set") + (set_attr "type" "alus_imm")] +) + (define_insn "addsi3_compareV_imm" [(set (reg:CC_V CC_REGNUM) (compare:CC_V @@ -1339,14 +1355,52 @@ (define_insn "*addsi3_carryin_clobercc" (set_attr "type" "adcs_reg")] ) -(define_expand "subv4" - [(match_operand:SIDI 0 "register_operand") - (match_operand:SIDI 1 "register_operand") - (match_operand:SIDI 2 "register_operand") +(define_expand "subvsi4" + [(match_operand:SI 0 "s_register_operand") + (match_operand:SI 1 "arm_rhs_operand") + (match_operand:SI 2 "arm_add_operand") + (match_operand 3 "")] + "TARGET_32BIT" +{ + if (CONST_INT_P (operands[1]) && CONST_INT_P (operands[2])) + { + /* If both operands are constants we can decide the result statically. */ + wi::overflow_type overflow; + wide_int val = wi::sub (rtx_mode_t (operands[1], SImode), + rtx_mode_t (operands[2], SImode), + SIGNED, &overflow); + emit_move_insn (operands[0], GEN_INT (val.to_shwi ())); + if (overflow != wi::OVF_NONE) + emit_jump_insn (gen_jump (operands[3])); + DONE; + } + else if (CONST_INT_P (operands[2])) + { + operands[2] = GEN_INT (-INTVAL (operands[2])); + /* Special case for INT_MIN. */ + if (INTVAL (operands[2]) == 0x80000000) + emit_insn (gen_subvsi3_intmin (operands[0], operands[1])); + else + emit_insn (gen_addsi3_compareV_imm (operands[0], operands[1], + operands[2])); + } + else if (CONST_INT_P (operands[1])) + emit_insn (gen_subvsi3_imm1 (operands[0], operands[1], operands[2])); + else + emit_insn (gen_subvsi3 (operands[0], operands[1], operands[2])); + + arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); + DONE; +}) + +(define_expand "subvdi4" + [(match_operand:DI 0 "s_register_operand") + (match_operand:DI 1 "s_register_operand") + (match_operand:DI 2 "s_register_operand") (match_operand 3 "")] "TARGET_32BIT" { - emit_insn (gen_sub3_compare1 (operands[0], operands[1], operands[2])); + emit_insn (gen_subdi3_compare1 (operands[0], operands[1], operands[2])); arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); DONE; @@ -1496,6 +1550,38 @@ (define_insn "subsi3_compare1" (set_attr "type" "alus_sreg")] ) +(define_insn "subvsi3" + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (minus:DI + (sign_extend:DI (match_operand:SI 1 "s_register_operand" "l,r")) + (sign_extend:DI (match_operand:SI 2 "s_register_operand" "l,r"))) + (sign_extend:DI (minus:SI (match_dup 1) (match_dup 2))))) + (set (match_operand:SI 0 "s_register_operand" "=l,r") + (minus:SI (match_dup 1) (match_dup 2)))] + "TARGET_32BIT" + "subs%?\\t%0, %1, %2" + [(set_attr "conds" "set") + (set_attr "arch" "t2,*") + (set_attr "length" "2,4") + (set_attr "type" "alus_sreg")] +) + +(define_insn "subvsi3_imm1" + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (minus:DI + (match_operand 1 "arm_immediate_operand" "I") + (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))) + (sign_extend:DI (minus:SI (match_dup 1) (match_dup 2))))) + (set (match_operand:SI 0 "s_register_operand" "=r") + (minus:SI (match_dup 1) (match_dup 2)))] + "TARGET_32BIT" + "rsbs%?\\t%0, %2, %1" + [(set_attr "conds" "set") + (set_attr "type" "alus_imm")] +) + (define_insn "subsi3_carryin" [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I,Pz")