From patchwork Fri Oct 18 19:48:32 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: 1179622 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511311-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="DqmR+gMx"; dkim-atps=neutral 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 46vxTG5yhFz9sP7 for ; Sat, 19 Oct 2019 06:50:10 +1100 (AEDT) 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=JVtq/gkDI2ehMhOK H+h/Aoe+WyyhnCJnd/E1TC0Y22OZX12NiqCXvmWS9rYtIlJ+F9Rv+YFRUWYeRDbg kk+uIsp4cW6x1JA0fGKnHmgGu58ATHvmaNCmqKA52Ejnp/slvAdAs0vd264MniPP hkCM7gJIuT5CbmPcmOUh5jqahEY= 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=pn5T8CvGWFwzX5Gu8MX0b9 4mLMw=; b=DqmR+gMxAbiZU9SA7g2ZVPKHjRdTSkoUbYZvH2za2t34+qy9OcIncC HALX+JF4qf05BTqpF1fnKEzPj4bcechLnsOLRrO0tjShZtkwo/vObkyw8jPJh2iQ rlzU+mDeetZcFdAFPsQocwn4LuTPR/a1+bZuzOktFjTbnbadlcqZo= Received: (qmail 77834 invoked by alias); 18 Oct 2019 19:49:36 -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 77588 invoked by uid 89); 18 Oct 2019 19:49:26 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_PASS autolearn=ham version=3.3.1 spammy= X-HELO: foss.arm.com Received: from Unknown (HELO foss.arm.com) (217.140.110.172) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 18 Oct 2019 19:49:21 +0000 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 202DC1597; Fri, 18 Oct 2019 12:49:13 -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 83E593F6C4; Fri, 18 Oct 2019 12:49:12 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 01/29] [arm] Rip out DImode addition and subtraction splits. Date: Fri, 18 Oct 2019 20:48:32 +0100 Message-Id: <20191018194900.34795-2-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 The first step towards early splitting of addition and subtraction at DImode is to rip out the old patterns that are designed to propagate DImode through the RTL optimization passes and the do late splitting. This patch does cause some code size regressions, but it should still execute correctly. We will progressively add back the optimizations we had here in later patches. A small number of tests in the Arm-specific testsuite do fail as a result of this patch, but that's to be expected, since the optimizations they are looking for have just been removed. I've kept the tests, but XFAILed them for now. One small technical change is also done in this patch as part of the cleanup: the uaddv4 expander is changed to use LTU as the branch comparison. This eliminates the need for CC_Cmode to recognize somewhat bogus equality constraints. gcc: * arm.md (adddi3): Only accept register operands. (arm_adddi3): Convert to simple insn with no split. Do not accept constants. (adddi_sesidi_di): Delete patern. (adddi_zesidi_di): Likewise. (uaddv4): Use LTU as condition for branch. (adddi3_compareV): Convert to simple insn with no split. (addsi3_compareV_upper): Delete pattern. (adddi3_compareC): Convert to simple insn with no split. Correct flags setting expression. (addsi3_compareC_upper): Delete pattern. (addsi3_compareC): Correct flags setting expression. (subdi3_compare1): Convert to simple insn with no split. (subsi3_carryin_compare): Delete pattern. (arm_subdi3): Convert to simple insn with no split. (subdi_zesidi): Delete pattern. (subdi_di_sesidi): Delete pattern. (subdi_zesidi_di): Delete pattern. (subdi_sesidi_di): Delete pattern. (subdi_zesidi_zesidi): Delete pattern. (negvdi3): Use s_register_operand. (negdi2_compare): Convert to simple insn with no split. (negdi2_insn): Likewise. (negsi2_carryin_compare): Delete pattern. (negdi_zero_extendsidi): Delete pattern. (arm_cmpdi_insn): Convert to simple insn with no split. (negdi2): Don't call gen_negdi2_neon. * config/arm/neon.md (adddi3_neon): Delete pattern. (subdi3_neon): Delete pattern. (negdi2_neon): Delete pattern. (splits for negdi2_neon): Delete splits. testsuite: * gcc.target/arm/negdi-3.c: Add XFAILS. * gcc.target/arm/pr3447-1.c: Likewise. * gcc.target/arm/pr3447-3.c: Likewise. * gcc.target/arm/pr3447-4.c: Likewise. --- gcc/config/arm/arm.c | 2 - gcc/config/arm/arm.md | 569 ++--------------------- gcc/testsuite/gcc.target/arm/negdi-3.c | 8 +- gcc/testsuite/gcc.target/arm/pr53447-1.c | 2 +- gcc/testsuite/gcc.target/arm/pr53447-3.c | 2 +- gcc/testsuite/gcc.target/arm/pr53447-4.c | 2 +- 6 files changed, 56 insertions(+), 529 deletions(-) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index ba330470141..41567af1869 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -23581,8 +23581,6 @@ maybe_get_arm_condition_code (rtx comparison) { case LTU: return ARM_CS; case GEU: return ARM_CC; - case NE: return ARM_CS; - case EQ: return ARM_CC; default: return ARM_NV; } diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index f861c72ccfc..241ba97c4ba 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -437,7 +437,7 @@ (define_expand "adddi3" [(parallel [(set (match_operand:DI 0 "s_register_operand") (plus:DI (match_operand:DI 1 "s_register_operand") - (match_operand:DI 2 "arm_adddi_operand"))) + (match_operand:DI 2 "s_register_operand"))) (clobber (reg:CC CC_REGNUM))])] "TARGET_EITHER" " @@ -446,87 +446,13 @@ (define_expand "adddi3" " ) -(define_insn_and_split "*arm_adddi3" - [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r,&r,&r") - (plus:DI (match_operand:DI 1 "arm_general_register_operand" "%0, 0, r, 0, r") - (match_operand:DI 2 "arm_general_adddi_operand" "r, 0, r, Dd, Dd"))) +(define_insn "*arm_adddi3" + [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r") + (plus:DI (match_operand:DI 1 "s_register_operand" " %0,0,r") + (match_operand:DI 2 "s_register_operand" " r,0,r"))) (clobber (reg:CC CC_REGNUM))] "TARGET_32BIT" - "#" - "TARGET_32BIT" - [(parallel [(set (reg:CC_C CC_REGNUM) - (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) - (match_dup 1))) - (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]) - (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5)) - (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] - " - { - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[4] = gen_highpart (SImode, operands[1]); - operands[1] = gen_lowpart (SImode, operands[1]); - operands[5] = gen_highpart_mode (SImode, DImode, operands[2]); - operands[2] = gen_lowpart (SImode, operands[2]); - }" - [(set_attr "conds" "clob") - (set_attr "length" "8") - (set_attr "type" "multiple")] -) - -(define_insn_and_split "*adddi_sesidi_di" - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") - (plus:DI (sign_extend:DI - (match_operand:SI 2 "s_register_operand" "r,r")) - (match_operand:DI 1 "s_register_operand" "0,r"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_32BIT" - "#" - "TARGET_32BIT && reload_completed" - [(parallel [(set (reg:CC_C CC_REGNUM) - (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) - (match_dup 1))) - (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]) - (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2) - (const_int 31)) - (match_dup 4)) - (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] - " - { - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[4] = gen_highpart (SImode, operands[1]); - operands[1] = gen_lowpart (SImode, operands[1]); - operands[2] = gen_lowpart (SImode, operands[2]); - }" - [(set_attr "conds" "clob") - (set_attr "length" "8") - (set_attr "type" "multiple")] -) - -(define_insn_and_split "*adddi_zesidi_di" - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") - (plus:DI (zero_extend:DI - (match_operand:SI 2 "s_register_operand" "r,r")) - (match_operand:DI 1 "s_register_operand" "0,r"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_32BIT" - "#" - "TARGET_32BIT && reload_completed" - [(parallel [(set (reg:CC_C CC_REGNUM) - (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) - (match_dup 1))) - (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]) - (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0)) - (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] - " - { - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[4] = gen_highpart (SImode, operands[1]); - operands[1] = gen_lowpart (SImode, operands[1]); - operands[2] = gen_lowpart (SImode, operands[2]); - }" + "adds\\t%Q0, %Q1, %Q2;adc\\t%R0, %R1, %R2" [(set_attr "conds" "clob") (set_attr "length" "8") (set_attr "type" "multiple")] @@ -553,7 +479,7 @@ (define_expand "uaddv4" "TARGET_32BIT" { emit_insn (gen_add3_compareC (operands[0], operands[1], operands[2])); - arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]); + arm_gen_unlikely_cbranch (LTU, CC_Cmode, operands[3]); DONE; }) @@ -636,44 +562,17 @@ (define_insn_and_split "*arm_addsi3" ] ) -(define_insn_and_split "adddi3_compareV" +(define_insn "adddi3_compareV" [(set (reg:CC_V CC_REGNUM) (ne:CC_V (plus:TI - (sign_extend:TI (match_operand:DI 1 "register_operand" "r")) - (sign_extend:TI (match_operand:DI 2 "register_operand" "r"))) + (sign_extend:TI (match_operand:DI 1 "s_register_operand" "r")) + (sign_extend:TI (match_operand:DI 2 "s_register_operand" "r"))) (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2))))) - (set (match_operand:DI 0 "register_operand" "=&r") + (set (match_operand:DI 0 "s_register_operand" "=&r") (plus:DI (match_dup 1) (match_dup 2)))] "TARGET_32BIT" - "#" - "&& reload_completed" - [(parallel [(set (reg:CC_C CC_REGNUM) - (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) - (match_dup 1))) - (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]) - (parallel [(set (reg:CC_V CC_REGNUM) - (ne:CC_V - (plus:DI (plus:DI - (sign_extend:DI (match_dup 4)) - (sign_extend:DI (match_dup 5))) - (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0))) - (plus:DI (sign_extend:DI - (plus:SI (match_dup 4) (match_dup 5))) - (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0))))) - (set (match_dup 3) (plus:SI (plus:SI - (match_dup 4) (match_dup 5)) - (ltu:SI (reg:CC_C CC_REGNUM) - (const_int 0))))])] - " - { - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[4] = gen_highpart (SImode, operands[1]); - operands[1] = gen_lowpart (SImode, operands[1]); - operands[5] = gen_highpart (SImode, operands[2]); - operands[2] = gen_lowpart (SImode, operands[2]); - }" + "adds\\t%Q0, %Q1, %Q2;adcs\\t%R0, %R1, %R2" [(set_attr "conds" "set") (set_attr "length" "8") (set_attr "type" "multiple")] @@ -694,99 +593,27 @@ (define_insn "addsi3_compareV" (set_attr "type" "alus_sreg")] ) -(define_insn "*addsi3_compareV_upper" - [(set (reg:CC_V CC_REGNUM) - (ne:CC_V - (plus:DI - (plus:DI - (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) - (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))) - (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0))) - (plus:DI (sign_extend:DI - (plus:SI (match_dup 1) (match_dup 2))) - (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0))))) - (set (match_operand:SI 0 "register_operand" "=r") - (plus:SI - (plus:SI (match_dup 1) (match_dup 2)) - (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] - "TARGET_32BIT" - "adcs%?\\t%0, %1, %2" - [(set_attr "conds" "set") - (set_attr "type" "adcs_reg")] -) - -(define_insn_and_split "adddi3_compareC" +(define_insn "adddi3_compareC" [(set (reg:CC_C CC_REGNUM) - (ne:CC_C - (plus:TI - (zero_extend:TI (match_operand:DI 1 "register_operand" "r")) - (zero_extend:TI (match_operand:DI 2 "register_operand" "r"))) - (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2))))) + (compare:CC_C + (plus:DI + (match_operand:DI 1 "register_operand" "r") + (match_operand:DI 2 "register_operand" "r")) + (match_dup 1))) (set (match_operand:DI 0 "register_operand" "=&r") (plus:DI (match_dup 1) (match_dup 2)))] "TARGET_32BIT" - "#" - "&& reload_completed" - [(parallel [(set (reg:CC_C CC_REGNUM) - (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) - (match_dup 1))) - (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]) - (parallel [(set (reg:CC_C CC_REGNUM) - (ne:CC_C - (plus:DI (plus:DI - (zero_extend:DI (match_dup 4)) - (zero_extend:DI (match_dup 5))) - (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0))) - (plus:DI (zero_extend:DI - (plus:SI (match_dup 4) (match_dup 5))) - (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0))))) - (set (match_dup 3) (plus:SI - (plus:SI (match_dup 4) (match_dup 5)) - (ltu:SI (reg:CC_C CC_REGNUM) - (const_int 0))))])] - " - { - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[4] = gen_highpart (SImode, operands[1]); - operands[5] = gen_highpart (SImode, operands[2]); - operands[1] = gen_lowpart (SImode, operands[1]); - operands[2] = gen_lowpart (SImode, operands[2]); - }" + "adds\\t%Q0, %Q1, %Q2;adcs\\t%R0, %R1, %R2" [(set_attr "conds" "set") (set_attr "length" "8") (set_attr "type" "multiple")] ) -(define_insn "*addsi3_compareC_upper" - [(set (reg:CC_C CC_REGNUM) - (ne:CC_C - (plus:DI - (plus:DI - (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) - (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))) - (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0))) - (plus:DI (zero_extend:DI - (plus:SI (match_dup 1) (match_dup 2))) - (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0))))) - (set (match_operand:SI 0 "register_operand" "=r") - (plus:SI - (plus:SI (match_dup 1) (match_dup 2)) - (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] - "TARGET_32BIT" - "adcs%?\\t%0, %1, %2" - [(set_attr "conds" "set") - (set_attr "type" "adcs_reg")] -) - (define_insn "addsi3_compareC" [(set (reg:CC_C CC_REGNUM) - (ne:CC_C - (plus:DI - (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) - (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))) - (zero_extend:DI - (plus:SI (match_dup 1) (match_dup 2))))) + (compare:CC_C (plus:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "register_operand" "r")) + (match_dup 1))) (set (match_operand:SI 0 "register_operand" "=r") (plus:SI (match_dup 1) (match_dup 2)))] "TARGET_32BIT" @@ -1094,31 +921,15 @@ (define_expand "usubv4" DONE; }) -(define_insn_and_split "subdi3_compare1" +(define_insn "subdi3_compare1" [(set (reg:CC CC_REGNUM) (compare:CC - (match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "register_operand" "r"))) - (set (match_operand:DI 0 "register_operand" "=&r") + (match_operand:DI 1 "s_register_operand" "r") + (match_operand:DI 2 "s_register_operand" "r"))) + (set (match_operand:DI 0 "s_register_operand" "=&r") (minus:DI (match_dup 1) (match_dup 2)))] "TARGET_32BIT" - "#" - "&& reload_completed" - [(parallel [(set (reg:CC CC_REGNUM) - (compare:CC (match_dup 1) (match_dup 2))) - (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) - (parallel [(set (reg:CC CC_REGNUM) - (compare:CC (match_dup 4) (match_dup 5))) - (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5)) - (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))])] - { - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[4] = gen_highpart (SImode, operands[1]); - operands[1] = gen_lowpart (SImode, operands[1]); - operands[5] = gen_highpart (SImode, operands[2]); - operands[2] = gen_lowpart (SImode, operands[2]); - } + "subs\\t%Q0, %Q1, %Q2;sbcs\\t%R0, %R1, %R2" [(set_attr "conds" "set") (set_attr "length" "8") (set_attr "type" "multiple")] @@ -1175,49 +986,6 @@ (define_insn "*subsi3_carryin_const0" (set_attr "type" "adc_imm")] ) -(define_insn "*subsi3_carryin_compare" - [(set (reg:CC CC_REGNUM) - (compare:CC (match_operand:SI 1 "s_register_operand" "r") - (match_operand:SI 2 "s_register_operand" "r"))) - (set (match_operand:SI 0 "s_register_operand" "=r") - (minus:SI (minus:SI (match_dup 1) (match_dup 2)) - (match_operand:SI 3 "arm_borrow_operation" "")))] - "TARGET_32BIT" - "sbcs\\t%0, %1, %2" - [(set_attr "conds" "set") - (set_attr "type" "adcs_reg")] -) - -(define_insn "*subsi3_carryin_compare_const" - [(set (reg:CC CC_REGNUM) - (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r") - (match_operand:SI 2 "const_int_I_operand" "I"))) - (set (match_operand:SI 0 "s_register_operand" "=r") - (minus:SI (plus:SI - (match_dup 1) - (match_operand:SI 3 "arm_neg_immediate_operand" "L")) - (match_operand:SI 4 "arm_borrow_operation" "")))] - "TARGET_32BIT - && (INTVAL (operands[2]) - == trunc_int_for_mode (-INTVAL (operands[3]), SImode))" - "sbcs\\t%0, %1, #%n3" - [(set_attr "conds" "set") - (set_attr "type" "adcs_imm")] -) - -(define_insn "*subsi3_carryin_compare_const0" - [(set (reg:CC CC_REGNUM) - (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r") - (const_int 0))) - (set (match_operand:SI 0 "s_register_operand" "=r") - (minus:SI (match_dup 1) - (match_operand:SI 2 "arm_borrow_operation" "")))] - "TARGET_32BIT" - "sbcs\\t%0, %1, #0" - [(set_attr "conds" "set") - (set_attr "type" "adcs_imm")] -) - (define_insn "*subsi3_carryin_shift" [(set (match_operand:SI 0 "s_register_operand" "=r") (minus:SI (minus:SI @@ -1286,166 +1054,19 @@ (define_expand "subdi3" [(parallel [(set (match_operand:DI 0 "s_register_operand") (minus:DI (match_operand:DI 1 "s_register_operand") - (match_operand:DI 2 "s_register_operand"))) + (match_operand:DI 2 "s_register_operand"))) (clobber (reg:CC CC_REGNUM))])] "TARGET_EITHER" " ") -(define_insn_and_split "*arm_subdi3" - [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r") +(define_insn "*arm_subdi3" + [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r") (minus:DI (match_operand:DI 1 "arm_general_register_operand" "0,r,0") (match_operand:DI 2 "arm_general_register_operand" "r,0,0"))) (clobber (reg:CC CC_REGNUM))] "TARGET_32BIT" - "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2" - "TARGET_32BIT" - [(parallel [(set (reg:CC CC_REGNUM) - (compare:CC (match_dup 1) (match_dup 2))) - (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) - (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5)) - (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))] - { - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[4] = gen_highpart (SImode, operands[1]); - operands[1] = gen_lowpart (SImode, operands[1]); - operands[5] = gen_highpart (SImode, operands[2]); - operands[2] = gen_lowpart (SImode, operands[2]); - } - [(set_attr "conds" "clob") - (set_attr "length" "8") - (set_attr "type" "multiple")] -) - -(define_insn_and_split "*subdi_di_zesidi" - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") - (minus:DI (match_operand:DI 1 "s_register_operand" "0,r") - (zero_extend:DI - (match_operand:SI 2 "s_register_operand" "r,r")))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_32BIT" - "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0" - "&& reload_completed" - [(parallel [(set (reg:CC CC_REGNUM) - (compare:CC (match_dup 1) (match_dup 2))) - (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) - (set (match_dup 3) (minus:SI (match_dup 4) - (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))] - { - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[4] = gen_highpart (SImode, operands[1]); - operands[1] = gen_lowpart (SImode, operands[1]); - } - [(set_attr "conds" "clob") - (set_attr "length" "8") - (set_attr "type" "multiple")] -) - -(define_insn_and_split "*subdi_di_sesidi" - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") - (minus:DI (match_operand:DI 1 "s_register_operand" "0,r") - (sign_extend:DI - (match_operand:SI 2 "s_register_operand" "r,r")))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_32BIT" - "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31" - "&& reload_completed" - [(parallel [(set (reg:CC CC_REGNUM) - (compare:CC (match_dup 1) (match_dup 2))) - (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) - (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) - (ashiftrt:SI (match_dup 2) - (const_int 31))) - (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))] - { - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[4] = gen_highpart (SImode, operands[1]); - operands[1] = gen_lowpart (SImode, operands[1]); - } - [(set_attr "conds" "clob") - (set_attr "length" "8") - (set_attr "type" "multiple")] -) - -(define_insn_and_split "*subdi_zesidi_di" - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") - (minus:DI (zero_extend:DI - (match_operand:SI 2 "s_register_operand" "r,r")) - (match_operand:DI 1 "s_register_operand" "0,r"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM" - "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0" - ; is equivalent to: - ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0" - "&& reload_completed" - [(parallel [(set (reg:CC CC_REGNUM) - (compare:CC (match_dup 2) (match_dup 1))) - (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))]) - (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4)) - (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))] - { - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[4] = gen_highpart (SImode, operands[1]); - operands[1] = gen_lowpart (SImode, operands[1]); - } - [(set_attr "conds" "clob") - (set_attr "length" "8") - (set_attr "type" "multiple")] -) - -(define_insn_and_split "*subdi_sesidi_di" - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") - (minus:DI (sign_extend:DI - (match_operand:SI 2 "s_register_operand" "r,r")) - (match_operand:DI 1 "s_register_operand" "0,r"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM" - "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31" - ; is equivalent to: - ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31" - "&& reload_completed" - [(parallel [(set (reg:CC CC_REGNUM) - (compare:CC (match_dup 2) (match_dup 1))) - (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))]) - (set (match_dup 3) (minus:SI (minus:SI - (ashiftrt:SI (match_dup 2) - (const_int 31)) - (match_dup 4)) - (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))] - { - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[4] = gen_highpart (SImode, operands[1]); - operands[1] = gen_lowpart (SImode, operands[1]); - } - [(set_attr "conds" "clob") - (set_attr "length" "8") - (set_attr "type" "multiple")] -) - -(define_insn_and_split "*subdi_zesidi_zesidi" - [(set (match_operand:DI 0 "s_register_operand" "=r") - (minus:DI (zero_extend:DI - (match_operand:SI 1 "s_register_operand" "r")) - (zero_extend:DI - (match_operand:SI 2 "s_register_operand" "r")))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_32BIT" - "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1" - "&& reload_completed" - [(parallel [(set (reg:CC CC_REGNUM) - (compare:CC (match_dup 1) (match_dup 2))) - (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) - (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1)) - (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))] - { - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - } + "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2" [(set_attr "conds" "clob") (set_attr "length" "8") (set_attr "type" "multiple")] @@ -4035,8 +3656,8 @@ (define_expand "negvsi3" }) (define_expand "negvdi3" - [(match_operand:DI 0 "register_operand") - (match_operand:DI 1 "register_operand") + [(match_operand:DI 0 "s_register_operand") + (match_operand:DI 1 "s_register_operand") (match_operand 2 "")] "TARGET_ARM" { @@ -4047,34 +3668,19 @@ (define_expand "negvdi3" }) -(define_insn_and_split "negdi2_compare" +(define_insn "negdi2_compare" [(set (reg:CC CC_REGNUM) (compare:CC (const_int 0) - (match_operand:DI 1 "register_operand" "0,r"))) - (set (match_operand:DI 0 "register_operand" "=r,&r") + (match_operand:DI 1 "register_operand" "r,r"))) + (set (match_operand:DI 0 "register_operand" "=&r,&r") (minus:DI (const_int 0) (match_dup 1)))] "TARGET_ARM" - "#" - "&& reload_completed" - [(parallel [(set (reg:CC CC_REGNUM) - (compare:CC (const_int 0) (match_dup 1))) - (set (match_dup 0) (minus:SI (const_int 0) - (match_dup 1)))]) - (parallel [(set (reg:CC CC_REGNUM) - (compare:CC (const_int 0) (match_dup 3))) - (set (match_dup 2) - (minus:SI - (minus:SI (const_int 0) (match_dup 3)) - (ltu:SI (reg:CC CC_REGNUM) - (const_int 0))))])] - { - operands[2] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[3] = gen_highpart (SImode, operands[1]); - operands[1] = gen_lowpart (SImode, operands[1]); - } + "@ + rsbs\\t%Q0, %Q1, #0;rscs\\t%R0, %R1, #0 + rsbs\\t%Q0, %Q1, #0;sbcs\\t%R0, %R1, %R1, lsl #1" [(set_attr "conds" "set") + (set_attr "arch" "a,t2") (set_attr "length" "8") (set_attr "type" "multiple")] ) @@ -4088,45 +3694,20 @@ (define_expand "negdi2" ) ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1). -;; The first alternative allows the common case of a *full* overlap. -(define_insn_and_split "*negdi2_insn" - [(set (match_operand:DI 0 "s_register_operand" "=r,&r") - (neg:DI (match_operand:DI 1 "s_register_operand" "0,r"))) +(define_insn "*negdi2_insn" + [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") + (neg:DI (match_operand:DI 1 "s_register_operand" "r,r"))) (clobber (reg:CC CC_REGNUM))] "TARGET_32BIT" - "#" ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0 (ARM) - ; negs %Q0, %Q1 ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2) - "TARGET_32BIT" - [(parallel [(set (reg:CC CC_REGNUM) - (compare:CC (const_int 0) (match_dup 1))) - (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))]) - (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3)) - (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))] - { - operands[2] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[3] = gen_highpart (SImode, operands[1]); - operands[1] = gen_lowpart (SImode, operands[1]); - } + "@ + rsbs\\t%Q0, %Q1, #0; rsc\\t%R0, %R1, #0 + negs\\t%Q0, %Q1; sbc\\t%R0, %R1, %R1, lsl #1" [(set_attr "conds" "clob") + (set_attr "arch" "a,t2") (set_attr "length" "8") (set_attr "type" "multiple")] ) -(define_insn "*negsi2_carryin_compare" - [(set (reg:CC CC_REGNUM) - (compare:CC (const_int 0) - (match_operand:SI 1 "s_register_operand" "r"))) - (set (match_operand:SI 0 "s_register_operand" "=r") - (minus:SI (minus:SI (const_int 0) - (match_dup 1)) - (match_operand:SI 2 "arm_borrow_operation" "")))] - "TARGET_ARM" - "rscs\\t%0, %1, #0" - [(set_attr "conds" "set") - (set_attr "type" "alus_imm")] -) - (define_expand "negsi2" [(set (match_operand:SI 0 "s_register_operand") (neg:SI (match_operand:SI 1 "s_register_operand")))] @@ -4249,29 +3830,6 @@ (define_insn_and_split "*negdi_extendsidi" (set_attr "type" "multiple")] ) -(define_insn_and_split "*negdi_zero_extendsidi" - [(set (match_operand:DI 0 "s_register_operand" "=r,&r") - (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r")))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_32BIT" - "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0" - ;; Don't care what register is input to sbc, - ;; since we just need to propagate the carry. - "&& reload_completed" - [(parallel [(set (reg:CC CC_REGNUM) - (compare:CC (const_int 0) (match_dup 1))) - (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))]) - (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2)) - (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))] - { - operands[2] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - } - [(set_attr "conds" "clob") - (set_attr "length" "8") - (set_attr "type" "multiple")] ;; length in thumb is 4 -) - ;; abssi2 doesn't really clobber the condition codes if a different register ;; is being set. To keep things simple, assume during rtl manipulations that ;; it does, but tell the final scan operator the truth. Similarly for @@ -6824,42 +6382,13 @@ (define_insn "*arm_cmpsi_negshiftsi_si" ;; if-conversion cannot reduce to a conditional compare, so we do ;; that directly. -(define_insn_and_split "*arm_cmpdi_insn" +(define_insn "*arm_cmpdi_insn" [(set (reg:CC_NCV CC_REGNUM) (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r") (match_operand:DI 1 "arm_di_operand" "rDi"))) (clobber (match_scratch:SI 2 "=r"))] "TARGET_32BIT" - "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1" - "&& reload_completed" - [(set (reg:CC CC_REGNUM) - (compare:CC (match_dup 0) (match_dup 1))) - (parallel [(set (reg:CC CC_REGNUM) - (compare:CC (match_dup 3) (match_dup 4))) - (set (match_dup 2) - (minus:SI (match_dup 5) - (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))])] - { - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - if (CONST_INT_P (operands[1])) - { - operands[4] = gen_highpart_mode (SImode, DImode, operands[1]); - if (operands[4] == const0_rtx) - operands[5] = operands[3]; - else - operands[5] = gen_rtx_PLUS (SImode, operands[3], - gen_int_mode (-UINTVAL (operands[4]), - SImode)); - } - else - { - operands[4] = gen_highpart (SImode, operands[1]); - operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]); - } - operands[1] = gen_lowpart (SImode, operands[1]); - operands[2] = gen_lowpart (SImode, operands[2]); - } + "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1" [(set_attr "conds" "set") (set_attr "length" "8") (set_attr "type" "multiple")] diff --git a/gcc/testsuite/gcc.target/arm/negdi-3.c b/gcc/testsuite/gcc.target/arm/negdi-3.c index 76ddf49fc0d..3f6f2d1c2bb 100644 --- a/gcc/testsuite/gcc.target/arm/negdi-3.c +++ b/gcc/testsuite/gcc.target/arm/negdi-3.c @@ -11,7 +11,7 @@ Expected output: rsbs r0, r0, #0 sbc r1, r1, r1 */ -/* { dg-final { scan-assembler-times "rsb" 1 } } */ -/* { dg-final { scan-assembler-times "sbc" 1 } } */ -/* { dg-final { scan-assembler-times "mov" 0 } } */ -/* { dg-final { scan-assembler-times "rsc" 0 } } */ +/* { dg-final { scan-assembler-times "rsb" 1 { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-times "sbc" 1 { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-times "mov" 0 { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-times "rsc" 0 { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/arm/pr53447-1.c b/gcc/testsuite/gcc.target/arm/pr53447-1.c index dc094180c85..0fd98b791fe 100644 --- a/gcc/testsuite/gcc.target/arm/pr53447-1.c +++ b/gcc/testsuite/gcc.target/arm/pr53447-1.c @@ -1,6 +1,6 @@ /* { dg-options "-O2" } */ /* { dg-require-effective-target arm32 } */ -/* { dg-final { scan-assembler-not "mov" } } */ +/* { dg-final { scan-assembler-not "mov" { xfail *-*-* } } } */ void t0p(long long * p) { diff --git a/gcc/testsuite/gcc.target/arm/pr53447-3.c b/gcc/testsuite/gcc.target/arm/pr53447-3.c index 8e48f119b74..79d3691ee14 100644 --- a/gcc/testsuite/gcc.target/arm/pr53447-3.c +++ b/gcc/testsuite/gcc.target/arm/pr53447-3.c @@ -1,6 +1,6 @@ /* { dg-options "-O2" } */ /* { dg-require-effective-target arm32 } */ -/* { dg-final { scan-assembler-not "mov" } } */ +/* { dg-final { scan-assembler-not "mov" { xfail *-*-* } } } */ void t0p(long long * p) diff --git a/gcc/testsuite/gcc.target/arm/pr53447-4.c b/gcc/testsuite/gcc.target/arm/pr53447-4.c index 22acb97270e..bfa20df7ccd 100644 --- a/gcc/testsuite/gcc.target/arm/pr53447-4.c +++ b/gcc/testsuite/gcc.target/arm/pr53447-4.c @@ -1,6 +1,6 @@ /* { dg-options "-O2" } */ /* { dg-require-effective-target arm32 } */ -/* { dg-final { scan-assembler-not "mov" } } */ +/* { dg-final { scan-assembler-not "mov" { xfail *-*-* } } } */ void t0p(long long * p) From patchwork Fri Oct 18 19:48:33 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: 1179621 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511310-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="j3b0AKBx"; dkim-atps=neutral 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 46vxT10hFbz9sPJ for ; Sat, 19 Oct 2019 06:49:56 +1100 (AEDT) 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=V1IjW4fpv3lSww51 AL2dEH6KvChmL6tHQsChDD3PTAuu56mBKEJShayLHu1/aPyoQUkE6UC4tjwGtB6f J1YiECPHYhE0ks4aQySxviwLB9kCzjytVsB6aZtvvOzW/VprdQIouF7FXmspqLfF xl9ZbtoXwRXlGfI8LQiZO8ky2qk= 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=+3M3wqhzGuu+UTnCQ+gPYk C+ibs=; b=j3b0AKBxx00GqnoKObD1a6hZ4CQmCjtCj/pdXcKVQi3rxT/7jpQVf+ 54X0VKd40b/kORp18CVWjCi0CYgYdvTm7fmZxekOI5Y+Re+SsEpWavN2WkzlB6Ol zaFjaSJLDdT8bapb/LTKdeW3SQQd/FI75vjvyCHRy0Qwn5BOmUZWQ= Received: (qmail 77769 invoked by alias); 18 Oct 2019 19:49:36 -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 77539 invoked by uid 89); 18 Oct 2019 19:49:23 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.3 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_PASS autolearn=ham version=3.3.1 spammy=addv X-HELO: foss.arm.com Received: from Unknown (HELO foss.arm.com) (217.140.110.172) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 18 Oct 2019 19:49:21 +0000 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 C959615A1; Fri, 18 Oct 2019 12:49:13 -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 557523F6C4; Fri, 18 Oct 2019 12:49:13 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 02/29] [arm] Perform early splitting of adddi3. Date: Fri, 18 Oct 2019 20:48:33 +0100 Message-Id: <20191018194900.34795-3-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 This patch causes the expansion of adddi3 to split the operation immediately for Arm and Thumb-2. This is desirable as it frees up the register allocator to pick what ever combination of registers suits best and reduces the number of auxiliary patterns that we need in the back-end. Three of the testcases that we disabled earlier are already fixed by this patch. Finally, we add a new pattern to match the canonicalization of add-with-carry when using an immediate of zero. gcc: * config/arm/arm-protos.h (arm_decompose_di_binop): New prototype. * config/arm/arm.c (arm_decompose_di_binop): New function. * config/arm/arm.md (adddi3): Also accept any const_int for op2. If not generating Thumb-1 code, decompose the operation into 32-bit pieces. * add0si_carryin_: New pattern. testsuite: * gcc.target/arm/pr53447-1.c: Remove XFAIL. * gcc.target/arm/pr53447-3.c: Remove XFAIL. * gcc.target/arm/pr53447-4.c: Remove XFAIL. --- gcc/config/arm/arm-protos.h | 1 + gcc/config/arm/arm.c | 15 +++++ gcc/config/arm/arm.md | 73 ++++++++++++++++++------ gcc/testsuite/gcc.target/arm/pr53447-1.c | 2 +- gcc/testsuite/gcc.target/arm/pr53447-3.c | 2 +- gcc/testsuite/gcc.target/arm/pr53447-4.c | 2 +- 6 files changed, 76 insertions(+), 19 deletions(-) diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index f995974f9bb..c685bcbf99c 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -57,6 +57,7 @@ extern rtx arm_simd_vect_par_cnst_half (machine_mode mode, bool high); extern bool arm_simd_check_vect_par_cnst_half_p (rtx op, machine_mode mode, bool high); extern void arm_emit_speculation_barrier_function (void); +extern void arm_decompose_di_binop (rtx, rtx, rtx *, rtx *, rtx *, rtx *); #ifdef RTX_CODE extern void arm_gen_unlikely_cbranch (enum rtx_code, machine_mode cc_mode, diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 41567af1869..db18651346f 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -14933,6 +14933,21 @@ gen_cpymem_ldrd_strd (rtx *operands) return true; } +/* Decompose operands for a 64-bit binary operation in OP1 and OP2 + into its component 32-bit subregs. OP2 may be an immediate + constant and we want to simplify it in that case. */ +void +arm_decompose_di_binop (rtx op1, rtx op2, rtx *lo_op1, rtx *hi_op1, + rtx *lo_op2, rtx *hi_op2) +{ + *lo_op1 = gen_lowpart (SImode, op1); + *hi_op1 = gen_highpart (SImode, op1); + *lo_op2 = simplify_gen_subreg (SImode, op2, DImode, + subreg_lowpart_offset (SImode, DImode)); + *hi_op2 = simplify_gen_subreg (SImode, op2, DImode, + subreg_highpart_offset (SImode, DImode)); +} + /* Select a dominance comparison mode if possible for a test of the general form (OP (COND_OR (X) (Y)) (const_int 0)). We support three forms. COND_OR == DOM_CC_X_AND_Y => (X && Y) diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 241ba97c4ba..5ba42a13430 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -437,25 +437,53 @@ (define_expand "adddi3" [(parallel [(set (match_operand:DI 0 "s_register_operand") (plus:DI (match_operand:DI 1 "s_register_operand") - (match_operand:DI 2 "s_register_operand"))) + (match_operand:DI 2 "reg_or_int_operand"))) (clobber (reg:CC CC_REGNUM))])] "TARGET_EITHER" " - if (TARGET_THUMB1 && !REG_P (operands[2])) - operands[2] = force_reg (DImode, operands[2]); - " -) + if (TARGET_THUMB1) + { + if (!REG_P (operands[2])) + operands[2] = force_reg (DImode, operands[2]); + } + else + { + rtx lo_result, hi_result, lo_dest, hi_dest; + rtx lo_op1, hi_op1, lo_op2, hi_op2; + arm_decompose_di_binop (operands[1], operands[2], &lo_op1, &hi_op1, + &lo_op2, &hi_op2); + lo_result = lo_dest = gen_lowpart (SImode, operands[0]); + hi_result = hi_dest = gen_highpart (SImode, operands[0]); + + if (lo_op2 == const0_rtx) + { + lo_dest = lo_op1; + if (!arm_add_operand (hi_op2, SImode)) + hi_op2 = force_reg (SImode, hi_op2); + /* Assume hi_op2 won't also be zero. */ + emit_insn (gen_addsi3 (hi_dest, hi_op1, hi_op2)); + } + else + { + if (!arm_add_operand (lo_op2, SImode)) + lo_op2 = force_reg (SImode, lo_op2); + if (!arm_not_operand (hi_op2, SImode)) + hi_op2 = force_reg (SImode, hi_op2); + + emit_insn (gen_addsi3_compareC (lo_dest, lo_op1, lo_op2)); + if (hi_op2 == const0_rtx) + emit_insn (gen_add0si3_carryin_ltu (hi_dest, hi_op1)); + else + emit_insn (gen_addsi3_carryin_ltu (hi_dest, hi_op1, hi_op2)); + } -(define_insn "*arm_adddi3" - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r") - (plus:DI (match_operand:DI 1 "s_register_operand" " %0,0,r") - (match_operand:DI 2 "s_register_operand" " r,0,r"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_32BIT" - "adds\\t%Q0, %Q1, %Q2;adc\\t%R0, %R1, %R2" - [(set_attr "conds" "clob") - (set_attr "length" "8") - (set_attr "type" "multiple")] + if (lo_result != lo_dest) + emit_move_insn (lo_result, lo_dest); + if (hi_result != hi_dest) + emit_move_insn (gen_highpart (SImode, operands[0]), hi_dest); + DONE; + } + " ) (define_expand "addv4" @@ -830,7 +858,7 @@ (define_insn "*compare_addsi2_op1" (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")] ) -(define_insn "*addsi3_carryin_" +(define_insn "addsi3_carryin_" [(set (match_operand:SI 0 "s_register_operand" "=l,r,r") (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r") (match_operand:SI 2 "arm_not_operand" "0,rI,K")) @@ -848,6 +876,19 @@ (define_insn "*addsi3_carryin_" (set_attr "type" "adc_reg,adc_reg,adc_imm")] ) +;; Canonicalization of the above when the immediate is zero. +(define_insn "add0si3_carryin_" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (plus:SI (LTUGEU:SI (reg: CC_REGNUM) (const_int 0)) + (match_operand:SI 1 "arm_not_operand" "r")))] + "TARGET_32BIT" + "adc%?\\t%0, %1, #0" + [(set_attr "conds" "use") + (set_attr "predicable" "yes") + (set_attr "length" "4") + (set_attr "type" "adc_imm")] +) + (define_insn "*addsi3_carryin_alt2_" [(set (match_operand:SI 0 "s_register_operand" "=l,r,r") (plus:SI (plus:SI (LTUGEU:SI (reg: CC_REGNUM) (const_int 0)) diff --git a/gcc/testsuite/gcc.target/arm/pr53447-1.c b/gcc/testsuite/gcc.target/arm/pr53447-1.c index 0fd98b791fe..dc094180c85 100644 --- a/gcc/testsuite/gcc.target/arm/pr53447-1.c +++ b/gcc/testsuite/gcc.target/arm/pr53447-1.c @@ -1,6 +1,6 @@ /* { dg-options "-O2" } */ /* { dg-require-effective-target arm32 } */ -/* { dg-final { scan-assembler-not "mov" { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-not "mov" } } */ void t0p(long long * p) { diff --git a/gcc/testsuite/gcc.target/arm/pr53447-3.c b/gcc/testsuite/gcc.target/arm/pr53447-3.c index 79d3691ee14..8e48f119b74 100644 --- a/gcc/testsuite/gcc.target/arm/pr53447-3.c +++ b/gcc/testsuite/gcc.target/arm/pr53447-3.c @@ -1,6 +1,6 @@ /* { dg-options "-O2" } */ /* { dg-require-effective-target arm32 } */ -/* { dg-final { scan-assembler-not "mov" { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-not "mov" } } */ void t0p(long long * p) diff --git a/gcc/testsuite/gcc.target/arm/pr53447-4.c b/gcc/testsuite/gcc.target/arm/pr53447-4.c index bfa20df7ccd..22acb97270e 100644 --- a/gcc/testsuite/gcc.target/arm/pr53447-4.c +++ b/gcc/testsuite/gcc.target/arm/pr53447-4.c @@ -1,6 +1,6 @@ /* { dg-options "-O2" } */ /* { dg-require-effective-target arm32 } */ -/* { dg-final { scan-assembler-not "mov" { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-not "mov" } } */ void t0p(long long * p) From patchwork Fri Oct 18 19:48:34 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: 1179623 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511312-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="JYKP3cvY"; dkim-atps=neutral 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 46vxTY0Kr5z9sP7 for ; Sat, 19 Oct 2019 06:50:24 +1100 (AEDT) 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=kBA4hWF2nrXAIZAR QsUUXBD8VhXMh3HYNybznF2JkjbHcKzulhgAJ7sE9g2vu3msjX1jw7a2s/9QNuzv Ft/dx+boto63TdOxbvtD+96XU77k5VZjsbzpp9Rxijqr87dSlBp29V3tqIcAvabZ bnI3lUOMg7epmmgWp+HLLGAdWlI= 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=GzGSerWzvFOro+zqdLkBvM Kyw3I=; b=JYKP3cvYxKoVvdqcz6WCJMW+VZ0f1Ixp7ciDUqZ68bEtAYU3qMVdST 1AkVyUIACT0fZ6NmTSC3D+XSKjOCvCBC8acK31oTpt+bukygtLx18P8UGMGzf50G ZVNhY2BZZzQogD6AzoOJi/YExiTiOxxvIvbFjNpGMfHm7wM2tECoQ= Received: (qmail 77908 invoked by alias); 18 Oct 2019 19:49:36 -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 77577 invoked by uid 89); 18 Oct 2019 19:49:26 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.4 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= X-HELO: foss.arm.com Received: from Unknown (HELO foss.arm.com) (217.140.110.172) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 18 Oct 2019 19:49:23 +0000 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 7B8D215BE; Fri, 18 Oct 2019 12:49:14 -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 090E73F6C4; Fri, 18 Oct 2019 12:49:13 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 03/29] [arm] Early split zero- and sign-extension Date: Fri, 18 Oct 2019 20:48:34 +0100 Message-Id: <20191018194900.34795-4-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 This patch changes the insn patterns for zero- and sign-extend into define_expands that generate the appropriate word operations immediately. * config/arm/arm.md (zero_extenddi2): Convert to define_expand. (extenddi2): Likewise. --- gcc/config/arm/arm.md | 75 +++++++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 21 deletions(-) diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 5ba42a13430..4a7a64e6613 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -4196,31 +4196,64 @@ (define_expand "truncdfhf2" ;; Zero and sign extension instructions. -(define_insn "zero_extenddi2" - [(set (match_operand:DI 0 "s_register_operand" "=r,?r") - (zero_extend:DI (match_operand:QHSI 1 "" - "")))] +(define_expand "zero_extenddi2" + [(set (match_operand:DI 0 "s_register_operand" "") + (zero_extend:DI (match_operand:QHSI 1 "" "")))] "TARGET_32BIT " - "#" - [(set_attr "length" "4,8") - (set_attr "arch" "*,*") - (set_attr "ce_count" "2") - (set_attr "predicable" "yes") - (set_attr "type" "mov_reg,multiple")] + { + rtx res_lo, res_hi, op0_lo, op0_hi; + res_lo = gen_lowpart (SImode, operands[0]); + res_hi = gen_highpart (SImode, operands[0]); + if (can_create_pseudo_p ()) + { + op0_lo = mode == SImode ? operands[1] : gen_reg_rtx (SImode); + op0_hi = gen_reg_rtx (SImode); + } + else + { + op0_lo = mode == SImode ? operands[1] : res_lo; + op0_hi = res_hi; + } + if (mode != SImode) + emit_insn (gen_rtx_SET (op0_lo, + gen_rtx_ZERO_EXTEND (SImode, operands[1]))); + emit_insn (gen_movsi (op0_hi, const0_rtx)); + if (res_lo != op0_lo) + emit_move_insn (res_lo, op0_lo); + if (res_hi != op0_hi) + emit_move_insn (res_hi, op0_hi); + DONE; + } ) -(define_insn "extenddi2" - [(set (match_operand:DI 0 "s_register_operand" "=r,?r,?r") - (sign_extend:DI (match_operand:QHSI 1 "" - "")))] +(define_expand "extenddi2" + [(set (match_operand:DI 0 "s_register_operand" "") + (sign_extend:DI (match_operand:QHSI 1 "" "")))] "TARGET_32BIT " - "#" - [(set_attr "length" "4,8,8") - (set_attr "ce_count" "2") - (set_attr "shift" "1") - (set_attr "predicable" "yes") - (set_attr "arch" "*,a,t") - (set_attr "type" "mov_reg,multiple,multiple")] + { + rtx res_lo, res_hi, op0_lo, op0_hi; + res_lo = gen_lowpart (SImode, operands[0]); + res_hi = gen_highpart (SImode, operands[0]); + if (can_create_pseudo_p ()) + { + op0_lo = mode == SImode ? operands[1] : gen_reg_rtx (SImode); + op0_hi = gen_reg_rtx (SImode); + } + else + { + op0_lo = mode == SImode ? operands[1] : res_lo; + op0_hi = res_hi; + } + if (mode != SImode) + emit_insn (gen_rtx_SET (op0_lo, + gen_rtx_SIGN_EXTEND (SImode, operands[1]))); + emit_insn (gen_ashrsi3 (op0_hi, op0_lo, GEN_INT (31))); + if (res_lo != op0_lo) + emit_move_insn (res_lo, op0_lo); + if (res_hi != op0_hi) + emit_move_insn (res_hi, op0_hi); + DONE; + } ) ;; Splits for all extensions to DImode From patchwork Fri Oct 18 19:48:35 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: 1179640 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511328-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="tM7yyLrU"; dkim-atps=neutral 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 46vxfx6w6Hz9sPK for ; Sat, 19 Oct 2019 06:58:33 +1100 (AEDT) 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=wpYaJfD+5oFDiV68 0t6SINaJxJB4lPC1wMMtrSQ71to7AX/HZx4N8PK2mspNE53qPJhIuDPle04bKXK6 A0Le992UMOcbhdCeAERazr3zhX3v+CeRr1gpi3cK0Gxwqv5VoSsOJKvZ5wzD9rlO Uo3WJ48nX+tkw3XvUKiuuOvKT5U= 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=eDOWUFFm/C876lVkRdgxr9 diI6o=; b=tM7yyLrUqJ/JQub1yZnD3k04pYX6tGi1nAX3CMcvVltOa7wM/Qsj/X oLrReE2MlUPNwMP41li9YfdM4/rTEgHT0Ebpfh1T09AfqahUPMf1MKDpbn0duoUl OjoLFwuzXCq1A+utwvVHnNJaJxVy5KM192q6pJ5i9Biakku0bbCA0= Received: (qmail 115127 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 114082 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, SPF_FAIL autolearn=ham version=3.3.1 spammy= 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-00055G-Bs for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:31 -0400 Received: from [217.140.110.172] (port=42746 helo=foss.arm.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1iLYLS-000549-5y 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 2F54815DB; Fri, 18 Oct 2019 12:49:15 -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 B0AE23F6C4; Fri, 18 Oct 2019 12:49:14 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 04/29] [arm] Rewrite addsi3_carryin_shift_ in canonical form Date: Fri, 18 Oct 2019 20:48:35 +0100 Message-Id: <20191018194900.34795-5-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 The add-with-carry operation which involves a shift doesn't match at present because it isn't matching the canonical form generated by combine. Fixing this is simply a matter of re-ordering the operands. * config/arm/arm.md (addsi3_carryin_shift_): Reorder operands to match canonical form. --- gcc/config/arm/arm.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 4a7a64e6613..9754a761faf 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -913,8 +913,8 @@ (define_insn "*addsi3_carryin_shift_" (match_operator:SI 2 "shift_operator" [(match_operand:SI 3 "s_register_operand" "r") (match_operand:SI 4 "reg_or_int_operand" "rM")]) - (match_operand:SI 1 "s_register_operand" "r")) - (LTUGEU:SI (reg: CC_REGNUM) (const_int 0))))] + (LTUGEU:SI (reg: CC_REGNUM) (const_int 0))) + (match_operand:SI 1 "s_register_operand" "r")))] "TARGET_32BIT" "adc%?\\t%0, %1, %3%S2" [(set_attr "conds" "use") From patchwork Fri Oct 18 19:48:36 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: 1179641 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511329-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="NEsgzL19"; dkim-atps=neutral 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 46vxgD6F19z9sP7 for ; Sat, 19 Oct 2019 06:58:48 +1100 (AEDT) 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=BNoSDwPeC6FFEer8 GONby45w+T8FSoUrdBbgKJWqJAgKbskX4DvMgkgQOJi4tHE6rB0u3U0ZsYaf4+st Bpp1KCVM7zwBePjzrLZ2C8KgzFkFsec/ZuOqfZS5j1YVuK41UV82VCHigst3KbsZ 4tw9dTmjBCFs6/vTaVVIyngHnjY= 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=8AD6NgOMhqhQKXLEODcTTG 4qQn0=; b=NEsgzL19/9loGAPf4+sAAIuYF31GIr6C8ziFjIuRppwGMBtIRmgwr1 bLj4a5SqptQniKwhOQIFoFZvX8w58kZuwsKXwTx0YLDh477Nebws7F57C4yMEDXl a7yr610ssowkZcv0225mRYFipTiytlE3A+3SltmRBchGPv7vjdgU0= Received: (qmail 115257 invoked by alias); 18 Oct 2019 19:55:47 -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 114936 invoked by uid 89); 18 Oct 2019 19:55:44 -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, KAM_NUMSUBJECT, SPF_FAIL autolearn=ham version=3.3.1 spammy=circumstances 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:43 +0000 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iLYLc-00059s-Pq for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:41 -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 1iLYLc-00054Y-Il for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:40 -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 D78FE15EC; Fri, 18 Oct 2019 12:49:15 -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 64BB73F6C4; Fri, 18 Oct 2019 12:49:15 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 05/29] [arm] fix constraints on addsi3_carryin_alt2 Date: Fri, 18 Oct 2019 20:48:36 +0100 Message-Id: <20191018194900.34795-6-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 addsi3_carryin_alt2 has a more strict constraint than the predicate when adding a constant. This leads to sub-optimal code in some circumstances. * config/arm/arm.md (addsi3_carryin_alt2): Use arm_not_operand for operand 2. --- gcc/config/arm/arm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 9754a761faf..fbe154a9873 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -893,7 +893,7 @@ (define_insn "*addsi3_carryin_alt2_" [(set (match_operand:SI 0 "s_register_operand" "=l,r,r") (plus:SI (plus:SI (LTUGEU:SI (reg: CC_REGNUM) (const_int 0)) (match_operand:SI 1 "s_register_operand" "%l,r,r")) - (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))] + (match_operand:SI 2 "arm_not_operand" "l,rI,K")))] "TARGET_32BIT" "@ adc%?\\t%0, %1, %2 From patchwork Fri Oct 18 19:48:37 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: 1179645 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511333-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="x5SmtRIf"; dkim-atps=neutral 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 46vxhD5Fl4z9sP7 for ; Sat, 19 Oct 2019 06:59:40 +1100 (AEDT) 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=m94FHqZ7MVrbKmIx 1o6Hn+C/XqXzGcetXBR1+n1qjaBY2WP5zgViTam5F3nsincio0gtXgkkI2fs4n5l 3a0pHYFYHj31B7bVZcOkPDVlzjN4RCOpDe7t5hPerFo4CwI+nAgWVE2TjN1muiYV y1g66mYdGSmm5y5IIRyP0K9xr+E= 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=tl/Ry+8YPxoKN9PzqaKmKx 5P1ls=; b=x5SmtRIfkZoDXFbQ8J8LZaLSF8y0wFGqQ+e8hdfUPgY0UyK59/2R/a HU9R2HVeMFjZaA6u2iaBSnCxrD0c1ZLlcVCMJSwFTwoeBVL7r6pQzaTejl8CVJPR SombfcLPaeHpU9XVC0pzr2E0lo4YQbnnwpbsD2PPt2mw3vGIMOnMM= Received: (qmail 118892 invoked by alias); 18 Oct 2019 19:56:15 -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 115560 invoked by uid 89); 18 Oct 2019 19:55:49 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-17.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_NUMSUBJECT, SPF_FAIL, UNSUBSCRIBE_BODY autolearn=ham version=3.3.1 spammy= 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:45 +0000 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iLYLd-0005BK-PE for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:43 -0400 Received: from [217.140.110.172] (port=42780 helo=foss.arm.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1iLYLd-000568-GV for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:41 -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 8B821161B; Fri, 18 Oct 2019 12:49:16 -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 18DA73F6C4; Fri, 18 Oct 2019 12:49:15 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 06/29] [arm] Early split subdi3 Date: Fri, 18 Oct 2019 20:48:37 +0100 Message-Id: <20191018194900.34795-7-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 adds early splitting of subdi3 so that the individual operations can be seen by the optimizers, particuarly combine. This should allow us to do at least as good a job as previously, but with far fewer patterns in the machine description. This is just the initial patch to add the early splitting. The cleanups will follow later. A special trick is used to handle the 'reverse subtract and compare' where a register is subtracted from a constant. The natural comparison (COMPARE (const) (reg)) is not canonical in this case and combine will never correctly generate it (trying to swap the order of the operands. To handle this we write the comparison as (COMPARE (NOT (reg)) (~const)), which has the same result for EQ, NE, LTU, LEU, GTU and GEU, which are all the cases we are really interested in here. Finally, we delete the negdi2 pattern. The generic expanders will use our new subdi3 expander if this pattern is missing and that can handle the negate case just fine. * config/arm/arm-modes.def (CC_RSB): New CC mode. * config/arm/predicates.md (arm_borrow_operation): Handle CC_RSBmode. * config/arm/arm.c (arm_select_cc_mode): Detect when we should return CC_RSBmode. (maybe_get_arm_condition_code): Handle CC_RSBmode. * config/arm/arm.md (subsi3_carryin): Make this pattern available to expand. (subdi3): Rewrite to early-expand the sub-operations. (rsb_im_compare): New pattern. (negdi2): Delete. (negdi2_insn): Delete. (arm_negsi2): Correct type attribute to alu_imm. (negsi2_0compare): New insn pattern. (negsi2_carryin): New insn pattern. --- gcc/config/arm/arm-modes.def | 4 + gcc/config/arm/arm.c | 23 ++++++ gcc/config/arm/arm.md | 141 ++++++++++++++++++++++++++++------- gcc/config/arm/predicates.md | 2 +- 4 files changed, 141 insertions(+), 29 deletions(-) diff --git a/gcc/config/arm/arm-modes.def b/gcc/config/arm/arm-modes.def index 8f131c369b5..4fa7f1b43e5 100644 --- a/gcc/config/arm/arm-modes.def +++ b/gcc/config/arm/arm-modes.def @@ -36,6 +36,9 @@ ADJUST_FLOAT_FORMAT (HF, ((arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE) CC_Nmode should be used if only the N (sign) flag is set correctly CC_CZmode should be used if only the C and Z flags are correct (used for DImode unsigned comparisons). + CC_RSBmode should be used where the comparison is set by an RSB immediate, + or NEG instruction. The form of the comparison for (const - reg) will + be (COMPARE (not (reg)) (~const)). CC_NCVmode should be used if only the N, C, and V flags are correct (used for DImode signed comparisons). CCmode should be used otherwise. */ @@ -45,6 +48,7 @@ CC_MODE (CC_Z); CC_MODE (CC_CZ); CC_MODE (CC_NCV); CC_MODE (CC_SWP); +CC_MODE (CC_RSB); CC_MODE (CCFP); CC_MODE (CCFPE); CC_MODE (CC_DNE); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index db18651346f..9a779e24cac 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -15214,6 +15214,17 @@ arm_select_cc_mode (enum rtx_code op, rtx x, rtx y) || (TARGET_32BIT && GET_CODE (x) == ZERO_EXTRACT))) return CC_NOOVmode; + /* An unsigned comparison of ~reg with a const is really a special + canoncialization of compare (~const, reg), which is a reverse + subtract operation. We may not get here if CONST is 0, but that + doesn't matter because ~0 isn't a valid immediate for RSB. */ + if (GET_MODE (x) == SImode + && GET_CODE (x) == NOT + && CONST_INT_P (y) + && (op == EQ || op == NE + || op == LTU || op == LEU || op == GEU || op == GTU)) + return CC_RSBmode; + if (GET_MODE (x) == QImode && (op == EQ || op == NE)) return CC_Zmode; @@ -23629,6 +23640,18 @@ maybe_get_arm_condition_code (rtx comparison) default: return ARM_NV; } + case E_CC_RSBmode: + switch (comp_code) + { + case NE: return ARM_NE; + case EQ: return ARM_EQ; + case GEU: return ARM_CS; + case GTU: return ARM_HI; + case LEU: return ARM_LS; + case LTU: return ARM_CC; + default: return ARM_NV; + } + case E_CCmode: switch (comp_code) { diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index fbe154a9873..99d931525f8 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -989,7 +989,7 @@ (define_insn "subsi3_compare1" (set_attr "type" "alus_sreg")] ) -(define_insn "*subsi3_carryin" +(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") (match_operand:SI 2 "s_register_operand" "r,r,r")) @@ -1094,12 +1094,72 @@ (define_expand "adddf3" (define_expand "subdi3" [(parallel [(set (match_operand:DI 0 "s_register_operand") - (minus:DI (match_operand:DI 1 "s_register_operand") + (minus:DI (match_operand:DI 1 "reg_or_int_operand") (match_operand:DI 2 "s_register_operand"))) (clobber (reg:CC CC_REGNUM))])] "TARGET_EITHER" " -") + if (TARGET_THUMB1) + { + if (!REG_P (operands[1])) + operands[1] = force_reg (DImode, operands[1]); + } + else + { + rtx lo_result, hi_result, lo_dest, hi_dest; + rtx lo_op1, hi_op1, lo_op2, hi_op2; + rtx condition; + + /* Since operands[1] may be an integer, pass it second, so that + any necessary simplifications will be done on the decomposed + constant. */ + arm_decompose_di_binop (operands[2], operands[1], &lo_op2, &hi_op2, + &lo_op1, &hi_op1); + lo_result = lo_dest = gen_lowpart (SImode, operands[0]); + hi_result = hi_dest = gen_highpart (SImode, operands[0]); + + if (!arm_rhs_operand (lo_op1, SImode)) + lo_op1 = force_reg (SImode, lo_op1); + + if ((TARGET_THUMB2 && ! s_register_operand (hi_op1, SImode)) + || !arm_rhs_operand (hi_op1, SImode)) + hi_op1 = force_reg (SImode, hi_op1); + + rtx cc_reg; + if (lo_op1 == const0_rtx) + { + cc_reg = gen_rtx_REG (CC_RSBmode, CC_REGNUM); + emit_insn (gen_negsi2_0compare (lo_dest, lo_op2)); + } + else if (CONST_INT_P (lo_op1)) + { + cc_reg = gen_rtx_REG (CC_RSBmode, CC_REGNUM); + emit_insn (gen_rsb_imm_compare (lo_dest, lo_op1, lo_op2, + GEN_INT (~UINTVAL (lo_op1)))); + } + else + { + cc_reg = gen_rtx_REG (CCmode, CC_REGNUM); + emit_insn (gen_subsi3_compare (lo_dest, lo_op1, lo_op2)); + } + + condition = gen_rtx_LTU (SImode, cc_reg, const0_rtx); + + if (hi_op1 == const0_rtx) + emit_insn (gen_negsi2_carryin (hi_dest, hi_op2, condition)); + else + emit_insn (gen_subsi3_carryin (hi_dest, hi_op1, hi_op2, condition)); + + if (lo_result != lo_dest) + emit_move_insn (lo_result, lo_dest); + + if (hi_result != hi_dest) + emit_move_insn (hi_result, hi_dest); + + DONE; + } + " +) (define_insn "*arm_subdi3" [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r") @@ -1213,7 +1273,23 @@ (define_insn "subsi3_compare" subs%?\\t%0, %1, %2 rsbs%?\\t%0, %2, %1" [(set_attr "conds" "set") - (set_attr "type" "alus_imm,alus_sreg,alus_sreg")] + (set_attr "type" "alus_imm,alus_sreg,alus_imm")] +) + +;; To keep the comparison in canonical form we express it as (~reg cmp ~0) +;; rather than (0 cmp reg). This gives the same results for unsigned +;; and equality compares which is what we mostly need here. +(define_insn "rsb_imm_compare" + [(set (reg:CC_RSB CC_REGNUM) + (compare:CC_RSB (not:SI (match_operand:SI 2 "s_register_operand" "r")) + (match_operand 3 "const_int_operand" ""))) + (set (match_operand:SI 0 "s_register_operand" "=r") + (minus:SI (match_operand 1 "arm_immediate_operand" "I") + (match_dup 2)))] + "TARGET_32BIT && ~UINTVAL (operands[1]) == UINTVAL (operands[3])" + "rsbs\\t%0, %2, %1" + [(set_attr "conds" "set") + (set_attr "type" "alus_imm")] ) (define_expand "subsf3" @@ -3726,29 +3802,6 @@ (define_insn "negdi2_compare" (set_attr "type" "multiple")] ) -(define_expand "negdi2" - [(parallel - [(set (match_operand:DI 0 "s_register_operand") - (neg:DI (match_operand:DI 1 "s_register_operand"))) - (clobber (reg:CC CC_REGNUM))])] - "TARGET_EITHER" -) - -;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1). -(define_insn "*negdi2_insn" - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") - (neg:DI (match_operand:DI 1 "s_register_operand" "r,r"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_32BIT" - "@ - rsbs\\t%Q0, %Q1, #0; rsc\\t%R0, %R1, #0 - negs\\t%Q0, %Q1; sbc\\t%R0, %R1, %R1, lsl #1" - [(set_attr "conds" "clob") - (set_attr "arch" "a,t2") - (set_attr "length" "8") - (set_attr "type" "multiple")] -) - (define_expand "negsi2" [(set (match_operand:SI 0 "s_register_operand") (neg:SI (match_operand:SI 1 "s_register_operand")))] @@ -3765,7 +3818,39 @@ (define_insn "*arm_negsi2" (set_attr "predicable_short_it" "yes,no") (set_attr "arch" "t2,*") (set_attr "length" "4") - (set_attr "type" "alu_sreg")] + (set_attr "type" "alu_imm")] +) + +;; To keep the comparison in canonical form we express it as (~reg cmp ~0) +;; rather than (0 cmp reg). This gives the same results for unsigned +;; and equality compares which is what we mostly need here. +(define_insn "negsi2_0compare" + [(set (reg:CC_RSB CC_REGNUM) + (compare:CC_RSB (not:SI (match_operand:SI 1 "s_register_operand" "l,r")) + (const_int -1))) + (set (match_operand:SI 0 "s_register_operand" "=l,r") + (neg:SI (match_dup 1)))] + "TARGET_32BIT" + "@ + negs\\t%0, %1 + rsbs\\t%0, %1, #0" + [(set_attr "conds" "set") + (set_attr "arch" "t2,*") + (set_attr "length" "2,*") + (set_attr "type" "alus_imm")] +) + +(define_insn "negsi2_carryin" + [(set (match_operand:SI 0 "s_register_operand" "=r,r") + (minus:SI (neg:SI (match_operand:SI 1 "s_register_operand" "r,r")) + (match_operand:SI 2 "arm_borrow_operation" "")))] + "TARGET_32BIT" + "@ + rsc\\t%0, %1, #0 + sbc\\t%0, %1, %1, lsl #1" + [(set_attr "conds" "use") + (set_attr "arch" "a,t2") + (set_attr "type" "adc_imm,adc_reg")] ) (define_expand "negsf2" diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md index 8b36e7ee462..e6766a97fc4 100644 --- a/gcc/config/arm/predicates.md +++ b/gcc/config/arm/predicates.md @@ -371,7 +371,7 @@ (define_special_predicate "arm_borrow_operation" machine_mode ccmode = GET_MODE (op0); if (ccmode == CC_Cmode) return GET_CODE (op) == GEU; - else if (ccmode == CCmode) + else if (ccmode == CCmode || ccmode == CC_RSBmode) return GET_CODE (op) == LTU; return false; } From patchwork Fri Oct 18 19:48:38 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: 1179649 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511337-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="f4JV2dh3"; dkim-atps=neutral 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 46vxjK0qwXz9sPJ for ; Sat, 19 Oct 2019 07:00:36 +1100 (AEDT) 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=UXgUqCrlKdM59R1Q sHoYwkT2M1qtLKIDwKjXhRrdFIf5ZdCQsF9/Ux7GD68NF3Mg4fWoeuZ+buZd/piW 1rhA1drx/BfC2eJeL8G07EpMOCRaUyWRStudu8PXX66wAQpwZiZ0bqBOU0LTOrhr iytONU7QHYWnybh1fNBbAorzfr4= 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=slV7eUVSo12GJKIDpY7iss /a/DQ=; b=f4JV2dh3eEaa7c37AT8cNDRtLrn1gBC+mz1KXyJk3/TJGNQhy/YpeC 2knBvvLiZ2ubzbFEaco/P/0tx+mhRRTl5vXert3azYo+BXxaX/Kws+o7JRnrtu8I 6JscW7v8uX0iZriGq8rtzsBXJx6FkpE5c/dYUowiDmg39a4ZmjSo8= Received: (qmail 122143 invoked by alias); 18 Oct 2019 19:56:39 -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 115937 invoked by uid 89); 18 Oct 2019 19:55:52 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-19.2 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= 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:49 +0000 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iLYLd-0005AX-5H for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:42 -0400 Received: from [217.140.110.172] (port=42764 helo=foss.arm.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1iLYLc-00055U-TV for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:41 -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 3F23B1650; Fri, 18 Oct 2019 12:49:17 -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 C0B7C3F6C4; Fri, 18 Oct 2019 12:49:16 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 07/29] [arm] Remove redundant DImode subtract patterns Date: Fri, 18 Oct 2019 20:48:38 +0100 Message-Id: <20191018194900.34795-8-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 Now that we early split DImode subtracts, the patterns to emit the original and to match zero-extend with subtraction or negation are no-longer useful. * config/arm/arm.md (arm_subdi3): Delete insn. (zextendsidi_negsi, negdi_extendsidi): Delete insn_and_split. --- gcc/config/arm/arm.md | 102 ------------------------------------------ 1 file changed, 102 deletions(-) diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 99d931525f8..f597a277c17 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -1161,18 +1161,6 @@ (define_expand "subdi3" " ) -(define_insn "*arm_subdi3" - [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r") - (minus:DI (match_operand:DI 1 "arm_general_register_operand" "0,r,0") - (match_operand:DI 2 "arm_general_register_operand" "r,0,0"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_32BIT" - "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2" - [(set_attr "conds" "clob") - (set_attr "length" "8") - (set_attr "type" "multiple")] -) - (define_expand "subsi3" [(set (match_operand:SI 0 "s_register_operand") (minus:SI (match_operand:SI 1 "reg_or_int_operand") @@ -3866,96 +3854,6 @@ (define_expand "negdf2" "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "") -(define_insn_and_split "*zextendsidi_negsi" - [(set (match_operand:DI 0 "s_register_operand" "=r") - (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))] - "TARGET_32BIT" - "#" - "" - [(set (match_dup 2) - (neg:SI (match_dup 1))) - (set (match_dup 3) - (const_int 0))] - { - operands[2] = gen_lowpart (SImode, operands[0]); - operands[3] = gen_highpart (SImode, operands[0]); - } - [(set_attr "length" "8") - (set_attr "type" "multiple")] -) - -;; Negate an extended 32-bit value. -(define_insn_and_split "*negdi_extendsidi" - [(set (match_operand:DI 0 "s_register_operand" "=l,r") - (neg:DI (sign_extend:DI - (match_operand:SI 1 "s_register_operand" "l,r")))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_32BIT" - "#" - "&& reload_completed" - [(const_int 0)] - { - rtx low = gen_lowpart (SImode, operands[0]); - rtx high = gen_highpart (SImode, operands[0]); - - if (reg_overlap_mentioned_p (low, operands[1])) - { - /* Input overlaps the low word of the output. Use: - asr Rhi, Rin, #31 - rsbs Rlo, Rin, #0 - rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */ - rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM); - - emit_insn (gen_rtx_SET (high, - gen_rtx_ASHIFTRT (SImode, operands[1], - GEN_INT (31)))); - - emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1])); - if (TARGET_ARM) - emit_insn (gen_rtx_SET (high, - gen_rtx_MINUS (SImode, - gen_rtx_MINUS (SImode, - const0_rtx, - high), - gen_rtx_LTU (SImode, - cc_reg, - const0_rtx)))); - else - { - rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1)); - emit_insn (gen_rtx_SET (high, - gen_rtx_MINUS (SImode, - gen_rtx_MINUS (SImode, - high, - two_x), - gen_rtx_LTU (SImode, - cc_reg, - const0_rtx)))); - } - } - else - { - /* No overlap, or overlap on high word. Use: - rsb Rlo, Rin, #0 - bic Rhi, Rlo, Rin - asr Rhi, Rhi, #31 - Flags not needed for this sequence. */ - emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1]))); - emit_insn (gen_rtx_SET (high, - gen_rtx_AND (SImode, - gen_rtx_NOT (SImode, operands[1]), - low))); - emit_insn (gen_rtx_SET (high, - gen_rtx_ASHIFTRT (SImode, high, - GEN_INT (31)))); - } - DONE; - } - [(set_attr "length" "12") - (set_attr "arch" "t2,*") - (set_attr "type" "multiple")] -) - ;; abssi2 doesn't really clobber the condition codes if a different register ;; is being set. To keep things simple, assume during rtl manipulations that ;; it does, but tell the final scan operator the truth. Similarly for From patchwork Fri Oct 18 19:48:39 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: 1179635 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511323-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="pFXwle3H"; dkim-atps=neutral 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 46vxdg73Lqz9sP7 for ; Sat, 19 Oct 2019 06:57:27 +1100 (AEDT) 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=ejUnwfsdJ8A6Ko0J FORCONtiUd9IrG1tpID2BkLLF5g6NKlR9e2k/YSbPiURKY0nLCUL6n+wTUxhOXqm cAvZ2xnvRKBkRvmIEgiQatMhGU/Ek51BJnzJnymlh+6PgPUjS7FOqKY7wD1k3idr ZcCWWkR0ydiW1nLpXY3xrFyweko= 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=yVHKZMIBdey38xM/uOqLKw y4Rww=; b=pFXwle3HMHt0Mmc1fh2So4a3AsOljKxuWF1HV4qS47/jJUlnR/Hz8V 3XZhZQa25z+B3VnThM4VlodmU5KMXjMe7lusRKpGFL01NYxW0RopMc9xw4cPzRIg twkMAhJKOoMo9kYfVTF5guiEJtd9ab+/lJGRScbhFIvNGOaUL7pk4= Received: (qmail 114604 invoked by alias); 18 Oct 2019 19:55:43 -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 113028 invoked by uid 89); 18 Oct 2019 19:55:41 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.9 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=minmax 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-00055m-PU for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:32 -0400 Received: from [217.140.110.172] (port=42752 helo=foss.arm.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1iLYLS-00054V-Go 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 E719E1655; Fri, 18 Oct 2019 12:49:17 -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 746793F6C4; Fri, 18 Oct 2019 12:49:17 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 08/29] [arm] Introduce arm_carry_operation Date: Fri, 18 Oct 2019 20:48:39 +0100 Message-Id: <20191018194900.34795-9-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 An earlier patch introduced arm_borrow_operation, this one introduces the carry variant, which is the same except that the logic of the carry-setting is inverted. Having done this we can now match more cases where the carry flag is propagated from comparisons with different modes without having to define even more patterns. A few small changes to the expand patterns are required to directly create the carry representation. The iterators LTUGEU is no-longer needed and removed, as is the code attribute 'cnb'. Finally, we fix a long-standing bug which was probably inert before: in Thumb2 a shift with ADC can only be by an immediate amount; register-specified shifts are not permitted. * config/arm/predicates.md (arm_carry_operation): New special predicate. * config/arm/iterators.md (LTUGEU): Delete iterator. (cnb): Delete code attribute. (optab): Delete ltu and geu elements. * config/arm/arm.md (addsi3_carryin): Renamed from addsi3_carryin_. Remove iterator and use arm_carry_operand. (add0si3_carryin): Similarly, but from add0si3_carryin_. (addsi3_carryin_alt2): Similarly, but from addsi3_carryin_alt2_. (addsi3_carryin_clobercc): Similarly. (addsi3_carryin_shift): Similarly. Do not allow register shifts in Thumb2 state. --- gcc/config/arm/arm.md | 36 ++++++++++++++++++++---------------- gcc/config/arm/iterators.md | 11 +---------- gcc/config/arm/predicates.md | 21 +++++++++++++++++++++ 3 files changed, 42 insertions(+), 26 deletions(-) diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index f597a277c17..f53dbc27207 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -471,10 +471,12 @@ (define_expand "adddi3" hi_op2 = force_reg (SImode, hi_op2); emit_insn (gen_addsi3_compareC (lo_dest, lo_op1, lo_op2)); + rtx carry = gen_rtx_LTU (SImode, gen_rtx_REG (CC_Cmode, CC_REGNUM), + const0_rtx); if (hi_op2 == const0_rtx) - emit_insn (gen_add0si3_carryin_ltu (hi_dest, hi_op1)); + emit_insn (gen_add0si3_carryin (hi_dest, hi_op1, carry)); else - emit_insn (gen_addsi3_carryin_ltu (hi_dest, hi_op1, hi_op2)); + emit_insn (gen_addsi3_carryin (hi_dest, hi_op1, hi_op2, carry)); } if (lo_result != lo_dest) @@ -858,11 +860,11 @@ (define_insn "*compare_addsi2_op1" (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")] ) -(define_insn "addsi3_carryin_" +(define_insn "addsi3_carryin" [(set (match_operand:SI 0 "s_register_operand" "=l,r,r") (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r") (match_operand:SI 2 "arm_not_operand" "0,rI,K")) - (LTUGEU:SI (reg: CC_REGNUM) (const_int 0))))] + (match_operand:SI 3 "arm_carry_operation" "")))] "TARGET_32BIT" "@ adc%?\\t%0, %1, %2 @@ -877,9 +879,9 @@ (define_insn "addsi3_carryin_" ) ;; Canonicalization of the above when the immediate is zero. -(define_insn "add0si3_carryin_" +(define_insn "add0si3_carryin" [(set (match_operand:SI 0 "s_register_operand" "=r") - (plus:SI (LTUGEU:SI (reg: CC_REGNUM) (const_int 0)) + (plus:SI (match_operand:SI 2 "arm_carry_operation" "") (match_operand:SI 1 "arm_not_operand" "r")))] "TARGET_32BIT" "adc%?\\t%0, %1, #0" @@ -889,9 +891,9 @@ (define_insn "add0si3_carryin_" (set_attr "type" "adc_imm")] ) -(define_insn "*addsi3_carryin_alt2_" +(define_insn "*addsi3_carryin_alt2" [(set (match_operand:SI 0 "s_register_operand" "=l,r,r") - (plus:SI (plus:SI (LTUGEU:SI (reg: CC_REGNUM) (const_int 0)) + (plus:SI (plus:SI (match_operand:SI 3 "arm_carry_operation" "") (match_operand:SI 1 "s_register_operand" "%l,r,r")) (match_operand:SI 2 "arm_not_operand" "l,rI,K")))] "TARGET_32BIT" @@ -907,28 +909,30 @@ (define_insn "*addsi3_carryin_alt2_" (set_attr "type" "adc_reg,adc_reg,adc_imm")] ) -(define_insn "*addsi3_carryin_shift_" - [(set (match_operand:SI 0 "s_register_operand" "=r") +(define_insn "*addsi3_carryin_shift" + [(set (match_operand:SI 0 "s_register_operand" "=r,r") (plus:SI (plus:SI (match_operator:SI 2 "shift_operator" - [(match_operand:SI 3 "s_register_operand" "r") - (match_operand:SI 4 "reg_or_int_operand" "rM")]) - (LTUGEU:SI (reg: CC_REGNUM) (const_int 0))) - (match_operand:SI 1 "s_register_operand" "r")))] + [(match_operand:SI 3 "s_register_operand" "r,r") + (match_operand:SI 4 "shift_amount_operand" "M,r")]) + (match_operand:SI 5 "arm_carry_operation" "")) + (match_operand:SI 1 "s_register_operand" "r,r")))] "TARGET_32BIT" "adc%?\\t%0, %1, %3%S2" [(set_attr "conds" "use") + (set_attr "arch" "32,a") + (set_attr "shift" "3") (set_attr "predicable" "yes") (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "") (const_string "alu_shift_imm") (const_string "alu_shift_reg")))] ) -(define_insn "*addsi3_carryin_clobercc_" +(define_insn "*addsi3_carryin_clobercc" [(set (match_operand:SI 0 "s_register_operand" "=r") (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r") (match_operand:SI 2 "arm_rhs_operand" "rI")) - (LTUGEU:SI (reg: CC_REGNUM) (const_int 0)))) + (match_operand:SI 3 "arm_carry_operation" ""))) (clobber (reg:CC CC_REGNUM))] "TARGET_32BIT" "adcs%?\\t%0, %1, %2" diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md index 8c9f7121951..77e1645083f 100644 --- a/gcc/config/arm/iterators.md +++ b/gcc/config/arm/iterators.md @@ -219,11 +219,6 @@ (define_mode_iterator VPF [V8QI V16QI V2SF V4SF]) ;; Code iterators ;;---------------------------------------------------------------------------- -;; A list of condition codes used in compare instructions where -;; the carry flag from the addition is used instead of doing the -;; compare a second time. -(define_code_iterator LTUGEU [ltu geu]) - ;; The signed gt, ge comparisons (define_code_iterator GTGE [gt ge]) @@ -809,13 +804,9 @@ (define_code_attr VQH_type [(plus "add") (smin "minmax") (smax "minmax") (define_code_attr VQH_sign [(plus "i") (smin "s") (smax "s") (umin "u") (umax "u")]) -(define_code_attr cnb [(ltu "CC_C") (geu "CC")]) - ;; Map rtl operator codes to optab names (define_code_attr optab - [(ltu "ltu") - (geu "geu") - (and "and") + [(and "and") (ior "ior") (xor "xor")]) diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md index e6766a97fc4..ed7495b69fc 100644 --- a/gcc/config/arm/predicates.md +++ b/gcc/config/arm/predicates.md @@ -356,6 +356,27 @@ (define_predicate "arm_comparison_operator_mode" (define_special_predicate "lt_ge_comparison_operator" (match_code "lt,ge")) +(define_special_predicate "arm_carry_operation" + (match_code "geu,ltu") + { + if (XEXP (op, 1) != const0_rtx) + return false; + + rtx op0 = XEXP (op, 0); + + if (!REG_P (op0) || REGNO (op0) != CC_REGNUM) + return false; + + machine_mode ccmode = GET_MODE (op0); + if (ccmode == CC_Cmode) + return GET_CODE (op) == LTU; + else if (ccmode == CCmode || ccmode == CC_RSBmode) + return GET_CODE (op) == GEU; + + return false; + } +) + ;; Match a "borrow" operation for use with SBC. The precise code will ;; depend on the form of the comparison. This is generally the inverse of ;; a carry operation, since the logic of SBC uses "not borrow" in it's From patchwork Fri Oct 18 19:48:40 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: 1179629 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511317-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="awq/kdfF"; dkim-atps=neutral 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 46vxcJ3562z9sP7 for ; Sat, 19 Oct 2019 06:56:16 +1100 (AEDT) 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=Gd4ZEtK6DwAVzEMl ksjKkNlYL7NCEN9jz3Mnq5LSuxv2dVesPht1jaDLeOX87SKtKVKRD1zWeYVWcZ01 N8SGkulcBhJEI91cVutAkEA/jLo6eNjKkUvu6Ky7b58D6DIX0QLPSOV7U6y0tO8V TcYGX0EHxgCxuqgTCwTuz7i3LDA= 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=17L78s3RW9fzbjCdbIKYc+ 6hv8o=; b=awq/kdfFmSI5Tk3/Mxwb7EoRxY1em3HRqr1T6e3Mfan+mi0XYdIkcm 79by6NO+AgoOg++w4efo4sxrYgAk0DT+OEXYxVLuFXxBv34BdSaYLffkCPMe89ql /aBStU069WgNDEv4IvagIMp32ZTLAk7WwceZ2F9Oou8ak/0M57UQs= Received: (qmail 112401 invoked by alias); 18 Oct 2019 19:55:40 -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 110383 invoked by uid 89); 18 Oct 2019 19:55:31 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_PASS autolearn=ham version=3.3.1 spammy=trickier, outer_code X-HELO: foss.arm.com Received: from Unknown (HELO foss.arm.com) (217.140.110.172) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 18 Oct 2019 19:55:30 +0000 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 9A81F1682; Fri, 18 Oct 2019 12:49:18 -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 282013F6C4; Fri, 18 Oct 2019 12:49:18 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 09/29] [arm] Correctly cost addition with a carry-in Date: Fri, 18 Oct 2019 20:48:40 +0100 Message-Id: <20191018194900.34795-10-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 The cost routine for Arm and Thumb2 was not recognising the idioms that describe the addition with carry, this results in the instructions appearing more expensive than they really are, which occasionally can lead to poor choices by combine. Recognising all the possible variants is a little trickier than normal because the expressions can become complex enough that this is no single canonical from. * config/arm/arm.c (strip_carry_operation): New function. (arm_rtx_costs_internal, case PLUS): Handle addtion with carry-in for SImode. --- gcc/config/arm/arm.c | 76 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 65 insertions(+), 11 deletions(-) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 9a779e24cac..dfbd5cde5eb 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -9504,6 +9504,20 @@ thumb1_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer) } } +/* Helper function for arm_rtx_costs. If one operand of the OP, a + PLUS, adds the carry flag, then return the other operand. If + neither is a carry, return OP unchanged. */ +static rtx +strip_carry_operation (rtx op) +{ + gcc_assert (GET_CODE (op) == PLUS); + if (arm_carry_operation (XEXP (op, 0), GET_MODE (op))) + return XEXP (op, 1); + else if (arm_carry_operation (XEXP (op, 1), GET_MODE (op))) + return XEXP (op, 0); + return op; +} + /* Helper function for arm_rtx_costs. If the operand is a valid shift operand, then return the operand that is being shifted. If the shift is not by a constant, then set SHIFT_REG to point to the operand. @@ -10253,8 +10267,41 @@ arm_rtx_costs_internal (rtx x, enum rtx_code code, enum rtx_code outer_code, return true; } + rtx op0 = XEXP (x, 0); + rtx op1 = XEXP (x, 1); + + /* Handle a side effect of adding in the carry to an addition. */ + if (GET_CODE (op0) == PLUS + && arm_carry_operation (op1, mode)) + { + op1 = XEXP (op0, 1); + op0 = XEXP (op0, 0); + } + else if (GET_CODE (op1) == PLUS + && arm_carry_operation (op0, mode)) + { + op0 = XEXP (op1, 0); + op1 = XEXP (op1, 1); + } + else if (GET_CODE (op0) == PLUS) + { + op0 = strip_carry_operation (op0); + if (swap_commutative_operands_p (op0, op1)) + std::swap (op0, op1); + } + + if (arm_carry_operation (op0, mode)) + { + /* Adding the carry to a register is a canonicalization of + adding 0 to the register plus the carry. */ + if (speed_p) + *cost += extra_cost->alu.arith; + *cost += rtx_cost (op1, mode, PLUS, 1, speed_p); + return true; + } + shift_reg = NULL; - shift_op = shifter_op_p (XEXP (x, 0), &shift_reg); + shift_op = shifter_op_p (op0, &shift_reg); if (shift_op != NULL) { if (shift_reg) @@ -10267,12 +10314,13 @@ arm_rtx_costs_internal (rtx x, enum rtx_code code, enum rtx_code outer_code, *cost += extra_cost->alu.arith_shift; *cost += (rtx_cost (shift_op, mode, ASHIFT, 0, speed_p) - + rtx_cost (XEXP (x, 1), mode, PLUS, 1, speed_p)); + + rtx_cost (op1, mode, PLUS, 1, speed_p)); return true; } - if (GET_CODE (XEXP (x, 0)) == MULT) + + if (GET_CODE (op0) == MULT) { - rtx mul_op = XEXP (x, 0); + rtx mul_op = op0; if (TARGET_DSP_MULTIPLY && ((GET_CODE (XEXP (mul_op, 0)) == SIGN_EXTEND @@ -10296,7 +10344,7 @@ arm_rtx_costs_internal (rtx x, enum rtx_code code, enum rtx_code outer_code, SIGN_EXTEND, 0, speed_p) + rtx_cost (XEXP (XEXP (mul_op, 1), 0), mode, SIGN_EXTEND, 0, speed_p) - + rtx_cost (XEXP (x, 1), mode, PLUS, 1, speed_p)); + + rtx_cost (op1, mode, PLUS, 1, speed_p)); return true; } @@ -10304,24 +10352,30 @@ arm_rtx_costs_internal (rtx x, enum rtx_code code, enum rtx_code outer_code, *cost += extra_cost->mult[0].add; *cost += (rtx_cost (XEXP (mul_op, 0), mode, MULT, 0, speed_p) + rtx_cost (XEXP (mul_op, 1), mode, MULT, 1, speed_p) - + rtx_cost (XEXP (x, 1), mode, PLUS, 1, speed_p)); + + rtx_cost (op1, mode, PLUS, 1, speed_p)); return true; } - if (CONST_INT_P (XEXP (x, 1))) + + if (CONST_INT_P (op1)) { int insns = arm_gen_constant (PLUS, SImode, NULL_RTX, - INTVAL (XEXP (x, 1)), NULL_RTX, + INTVAL (op1), NULL_RTX, NULL_RTX, 1, 0); *cost = COSTS_N_INSNS (insns); if (speed_p) *cost += insns * extra_cost->alu.arith; - *cost += rtx_cost (XEXP (x, 0), mode, PLUS, 0, speed_p); + *cost += rtx_cost (op0, mode, PLUS, 0, speed_p); return true; } - else if (speed_p) + + if (speed_p) *cost += extra_cost->alu.arith; - return false; + /* Don't recurse here because we want to test the operands + without any carry operation. */ + *cost += rtx_cost (op0, mode, PLUS, 0, speed_p); + *cost += rtx_cost (op1, mode, PLUS, 1, speed_p); + return true; } if (mode == DImode) From patchwork Fri Oct 18 19:48:41 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: 1179628 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511315-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="V++tQckJ"; dkim-atps=neutral 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 46vxc44NQHz9sPJ for ; Sat, 19 Oct 2019 06:56:04 +1100 (AEDT) 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=xO8dyjmFs4MJm/4v 1T8Iip0Sf3PFUlaHU+E1E2ydeFLplw1eiZL2lgmAx0xF8tR2zpmAdRtFHrHoLXxt yPMoKs9c5kcw/DmHI5A3cH2aWVQZAYOJujBIwe5MMDmoL7LZI7pwO/NA3oXwNdy9 lnaMOItCXrevTsr/51LFiqoRn38= 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=WQA6J1T750MXg8+cT6GrvL sLXNA=; b=V++tQckJK0+FHEJ75+m8QX2MFT+84Oj61j44t1mV+Y5JRFZULpQYrG ArtFkgtYVLQUC8IOVJ0myuMNwWnY0z0am8+4a7EKtANsv1Fx+JswJtD1AtCv0bUQ vPQywzAXJOOWGUDk3XE3vrQBhGWquawWIbL9arAPWiH+0VYisPqc4= Received: (qmail 111649 invoked by alias); 18 Oct 2019 19:55:39 -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 110346 invoked by uid 89); 18 Oct 2019 19:55:31 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.5 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_PASS autolearn=ham version=3.3.1 spammy=expressing, HX-Languages-Length:2913, outer_code X-HELO: foss.arm.com Received: from Unknown (HELO foss.arm.com) (217.140.110.172) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 18 Oct 2019 19:55:30 +0000 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 4E82A1691; Fri, 18 Oct 2019 12:49:19 -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 CFF943F6C4; Fri, 18 Oct 2019 12:49:18 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 10/29] [arm] Correct cost calculations involving borrow for subtracts. Date: Fri, 18 Oct 2019 20:48:41 +0100 Message-Id: <20191018194900.34795-11-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 The rtx_cost calculations when a borrow operation was being performed were not being calculated correctly. The borrow is free as part of the subtract-with-carry instructions. This patch recognizes the various idioms that can describe this and returns the correct costs. * config/arm/arm.c (arm_rtx_costs_internal, case MINUS): Handle borrow operations. --- gcc/config/arm/arm.c | 49 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index dfbd5cde5eb..b91b52f6d51 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -10049,15 +10049,46 @@ arm_rtx_costs_internal (rtx x, enum rtx_code code, enum rtx_code outer_code, rtx shift_by_reg = NULL; rtx shift_op; rtx non_shift_op; + rtx op0 = XEXP (x, 0); + rtx op1 = XEXP (x, 1); - shift_op = shifter_op_p (XEXP (x, 0), &shift_by_reg); + /* Factor out any borrow operation. There's more than one way + of expressing this; try to recognize them all. */ + if (GET_CODE (op0) == MINUS) + { + if (arm_borrow_operation (op1, SImode)) + { + op1 = XEXP (op0, 1); + op0 = XEXP (op0, 0); + } + else if (arm_borrow_operation (XEXP (op0, 1), SImode)) + op0 = XEXP (op0, 0); + } + else if (GET_CODE (op1) == PLUS + && arm_borrow_operation (XEXP (op1, 0), SImode)) + op1 = XEXP (op1, 0); + else if (GET_CODE (op0) == NEG + && arm_borrow_operation (op1, SImode)) + { + /* Negate with carry-in. For Thumb2 this is done with + SBC R, X, X lsl #1 (ie X - 2X - C) as Thumb lacks the + RSC instruction that exists in Arm mode. */ + if (speed_p) + *cost += (TARGET_THUMB2 + ? extra_cost->alu.arith_shift + : extra_cost->alu.arith); + *cost += rtx_cost (XEXP (op0, 0), mode, MINUS, 0, speed_p); + return true; + } + + shift_op = shifter_op_p (op0, &shift_by_reg); if (shift_op == NULL) { - shift_op = shifter_op_p (XEXP (x, 1), &shift_by_reg); - non_shift_op = XEXP (x, 0); + shift_op = shifter_op_p (op1, &shift_by_reg); + non_shift_op = op0; } else - non_shift_op = XEXP (x, 1); + non_shift_op = op1; if (shift_op != NULL) { @@ -10087,10 +10118,10 @@ arm_rtx_costs_internal (rtx x, enum rtx_code code, enum rtx_code outer_code, return true; } - if (CONST_INT_P (XEXP (x, 0))) + if (CONST_INT_P (op0)) { int insns = arm_gen_constant (MINUS, SImode, NULL_RTX, - INTVAL (XEXP (x, 0)), NULL_RTX, + INTVAL (op0), NULL_RTX, NULL_RTX, 1, 0); *cost = COSTS_N_INSNS (insns); if (speed_p) @@ -10101,7 +10132,11 @@ arm_rtx_costs_internal (rtx x, enum rtx_code code, enum rtx_code outer_code, else if (speed_p) *cost += extra_cost->alu.arith; - return false; + /* Don't recurse as we don't want to cost any borrow that + we've stripped. */ + *cost += rtx_cost (op0, mode, MINUS, 0, speed_p); + *cost += rtx_cost (op1, mode, MINUS, 1, speed_p); + return true; } if (GET_MODE_CLASS (mode) == MODE_INT From patchwork Fri Oct 18 19:48:42 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: 1179633 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511321-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="PBDi5aLl"; dkim-atps=neutral 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 46vxdD6BFzz9sP7 for ; Sat, 19 Oct 2019 06:57:03 +1100 (AEDT) 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=aKj6qFQSyMdMcr8q P9H9pzOI2XJ9/hKhNB8p7c2zKlwAz7c6o1iKmph3NppuNmvoc7ooqntJm3Ql8uEr u8Qb40GA5Pnza9bMABknUR5qGq/pH48Rn82dtBi0NwVW63HUoX3ueoo59fIP4fG+ OM0xLqST4A6mV6JsQPBIVkXxbJM= 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=OQLRzcMh/sM7YRMrj38x7p de7B0=; b=PBDi5aLloQZziVyKeC/KDKMsLkjI5At7+asSAKA1aG98ymtyOT5yLG n3tmDfoWPHMX0MbUDnZn1JCib7lmr1ff8WwehGD2hFR9zM0NTwU6HCoAOdc2oEcS y+YGAAgnKdxILAgSL2gjjE5/1xpu6RE6NouscVHmKNZXt3tKHPF1M= Received: (qmail 113622 invoked by alias); 18 Oct 2019 19:55:42 -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 110798 invoked by uid 89); 18 Oct 2019 19:55:37 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.7 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=practically, REG_DEAD, reg_dead, disappear 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:34 +0000 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iLYLR-00054R-Ti for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:31 -0400 Received: from [217.140.110.172] (port=42746 helo=foss.arm.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1iLYLR-000549-LH for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:29 -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 026DD1692; Fri, 18 Oct 2019 12:49:20 -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 83C123F6C4; Fri, 18 Oct 2019 12:49:19 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 11/29] [arm] Reduce cost of insns that are simple reg-reg moves. Date: Fri, 18 Oct 2019 20:48:42 +0100 Message-Id: <20191018194900.34795-12-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 Consider this sequence during combine: Trying 18, 7 -> 22: 18: r118:SI=r122:SI REG_DEAD r122:SI 7: r114:SI=0x1-r118:SI-ltu(cc:CC_RSB,0) REG_DEAD r118:SI REG_DEAD cc:CC_RSB 22: r1:SI=r114:SI REG_DEAD r114:SI Failed to match this instruction: (set (reg:SI 1 r1 [+4 ]) (minus:SI (geu:SI (reg:CC_RSB 100 cc) (const_int 0 [0])) (reg:SI 122))) Successfully matched this instruction: (set (reg:SI 114) (geu:SI (reg:CC_RSB 100 cc) (const_int 0 [0]))) Successfully matched this instruction: (set (reg:SI 1 r1 [+4 ]) (minus:SI (reg:SI 114) (reg:SI 122))) allowing combination of insns 18, 7 and 22 original costs 4 + 4 + 4 = 12 replacement costs 8 + 4 = 12 The costs are all correct, but we really don't want this combination to take place. The original costs contain an insn that is a simple move of one pseudo register to another and it is extremely likely that register allocation will eliminate this insn entirely. On the other hand, the resulting sequence really does expand into a sequence that costs 12 (ie 3 insns). We don't want to prevent combine from eliminating such moves, as this can expose more combine opportunities, but we shouldn't rate them as profitable in themselves. We can do this be adjusting the costs slightly so that the benefit of eliminating such a simple insn is reduced. We only do this before register allocation; after allocation we give such insns their full cost. * config/arm/arm.c (arm_insn_cost): New function. (TARGET_INSN_COST): Override default definition. --- gcc/config/arm/arm.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index b91b52f6d51..e33b6b14d28 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -181,6 +181,7 @@ static bool arm_have_conditional_execution (void); static bool arm_cannot_force_const_mem (machine_mode, rtx); static bool arm_legitimate_constant_p (machine_mode, rtx); static bool arm_rtx_costs (rtx, machine_mode, int, int, int *, bool); +static int arm_insn_cost (rtx_insn *, bool); static int arm_address_cost (rtx, machine_mode, addr_space_t, bool); static int arm_register_move_cost (machine_mode, reg_class_t, reg_class_t); static int arm_memory_move_cost (machine_mode, reg_class_t, bool); @@ -510,6 +511,8 @@ static const struct attribute_spec arm_attribute_table[] = #define TARGET_RTX_COSTS arm_rtx_costs #undef TARGET_ADDRESS_COST #define TARGET_ADDRESS_COST arm_address_cost +#undef TARGET_INSN_COST +#define TARGET_INSN_COST arm_insn_cost #undef TARGET_SHIFT_TRUNCATION_MASK #define TARGET_SHIFT_TRUNCATION_MASK arm_shift_truncation_mask @@ -11486,6 +11489,24 @@ arm_rtx_costs (rtx x, machine_mode mode ATTRIBUTE_UNUSED, int outer_code, return result; } +static int +arm_insn_cost (rtx_insn *insn, bool speed) +{ + int cost; + + /* Don't cost a simple reg-reg move at a full insn cost: such moves + will likely disappear during register allocation. */ + if (!reload_completed + && GET_CODE (PATTERN (insn)) == SET + && REG_P (SET_DEST (PATTERN (insn))) + && REG_P (SET_SRC (PATTERN (insn)))) + return 2; + cost = pattern_cost (PATTERN (insn), speed); + /* If the cost is zero, then it's likely a complex insn. We don't want the + cost of these to be less than something we know about. */ + return cost ? cost : COSTS_N_INSNS (2); +} + /* All address computations that can be done are free, but rtx cost returns the same for practically all of them. So we weight the different types of address here in the order (most pref first): From patchwork Fri Oct 18 19:48:43 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: 1179630 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511318-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="VoiOVQ2N"; dkim-atps=neutral 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 46vxcX0Hr5z9sP7 for ; Sat, 19 Oct 2019 06:56:27 +1100 (AEDT) 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=HNacEcNlSisU5+Xh hI7DkhfGd236rIzxluVsyv8AD+8gaOhjVHJP8nfUqbyVVQI8ez7S0E07Foy/1xHa LWTBuD8gYf5afdBVLfuuEUx3YTuLgCITX7CwqVkvUjaHgOufcytQfTX/MCOAT18P eJn79oe7eM1YZyMyNfGsA46W8T0= 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=Gczxutf7Ke88xfCC+GJ1Mz elo8w=; b=VoiOVQ2NZXlOaXOtGLHwHivlej037mB4/5uny+MYz5LU387dcYlrK+ X5K8X/5bFhpGovva1SHmORziis4PCSaEOg9oZ3a2A6FZpMUEXJ+XLGgivoAUeMiA StoF3/8DSFpIHnGYtrSryKttrTlraK9bHooXrgeJYY25KxoCOU1Jw= Received: (qmail 112567 invoked by alias); 18 Oct 2019 19:55:40 -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 110353 invoked by uid 89); 18 Oct 2019 19:55:31 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_PASS autolearn=ham version=3.3.1 spammy=if_then_else X-HELO: foss.arm.com Received: from Unknown (HELO foss.arm.com) (217.140.110.172) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 18 Oct 2019 19:55:30 +0000 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 AA30F169C; Fri, 18 Oct 2019 12:49:20 -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 378DA3F6C4; Fri, 18 Oct 2019 12:49:20 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 12/29] [arm] Implement negscc using SBC when appropriate. Date: Fri, 18 Oct 2019 20:48:43 +0100 Message-Id: <20191018194900.34795-13-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 When the carry flag is appropriately set by a comprison, negscc patterns can expand into a simple SBC of a register with itself. This means we can convert two conditional instructions into a single non-conditional instruction. Furthermore, in Thumb2 we can avoid the need for an IT instruction as well. This patch also fixes the remaining testcase that we initially XFAILed in the first patch of this series. gcc: * config/arm/arm.md (negscc_borrow): New pattern. (mov_negscc): Don't split if the insn would match negscc_borrow. * config/arm/thumb2.md (thumb2_mov_negscc): Likewise. (thumb2_mov_negscc_strict_it): Likewise. testsuite: * gcc.target/arm/negdi-3.c: Remove XFAIL markers. --- gcc/config/arm/arm.md | 14 ++++++++++++-- gcc/config/arm/thumb2.md | 8 ++++++-- gcc/testsuite/gcc.target/arm/negdi-3.c | 8 ++++---- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index f53dbc27207..74f417fbe4b 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -6612,13 +6612,23 @@ (define_insn_and_split "*mov_scc" (set_attr "type" "multiple")] ) +(define_insn "*negscc_borrow" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (neg:SI (match_operand:SI 1 "arm_borrow_operation" "")))] + "TARGET_32BIT" + "sbc\\t%0, %0, %0" + [(set_attr "conds" "use") + (set_attr "length" "4") + (set_attr "type" "adc_reg")] +) + (define_insn_and_split "*mov_negscc" [(set (match_operand:SI 0 "s_register_operand" "=r") (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode" [(match_operand 2 "cc_register" "") (const_int 0)])))] - "TARGET_ARM" + "TARGET_ARM && !arm_borrow_operation (operands[1], SImode)" "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0" - "TARGET_ARM" + "&& true" [(set (match_dup 0) (if_then_else:SI (match_dup 1) (match_dup 3) diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md index 6ccc875e2b4..8d0b6be9205 100644 --- a/gcc/config/arm/thumb2.md +++ b/gcc/config/arm/thumb2.md @@ -368,7 +368,9 @@ (define_insn_and_split "*thumb2_mov_negscc" [(set (match_operand:SI 0 "s_register_operand" "=r") (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode" [(match_operand 2 "cc_register" "") (const_int 0)])))] - "TARGET_THUMB2 && !arm_restrict_it" + "TARGET_THUMB2 + && !arm_restrict_it + && !arm_borrow_operation (operands[1], SImode)" "#" ; "ite\\t%D1\;mov%D1\\t%0, #0\;mvn%d1\\t%0, #0" "&& true" [(set (match_dup 0) @@ -387,7 +389,9 @@ (define_insn_and_split "*thumb2_mov_negscc_strict_it" [(set (match_operand:SI 0 "low_register_operand" "=l") (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode" [(match_operand 2 "cc_register" "") (const_int 0)])))] - "TARGET_THUMB2 && arm_restrict_it" + "TARGET_THUMB2 + && arm_restrict_it + && !arm_borrow_operation (operands[1], SImode)" "#" ; ";mvn\\t%0, #0 ;it\\t%D1\;mov%D1\\t%0, #0\" "&& reload_completed" [(set (match_dup 0) diff --git a/gcc/testsuite/gcc.target/arm/negdi-3.c b/gcc/testsuite/gcc.target/arm/negdi-3.c index 3f6f2d1c2bb..76ddf49fc0d 100644 --- a/gcc/testsuite/gcc.target/arm/negdi-3.c +++ b/gcc/testsuite/gcc.target/arm/negdi-3.c @@ -11,7 +11,7 @@ Expected output: rsbs r0, r0, #0 sbc r1, r1, r1 */ -/* { dg-final { scan-assembler-times "rsb" 1 { xfail *-*-* } } } */ -/* { dg-final { scan-assembler-times "sbc" 1 { xfail *-*-* } } } */ -/* { dg-final { scan-assembler-times "mov" 0 { xfail *-*-* } } } */ -/* { dg-final { scan-assembler-times "rsc" 0 { xfail *-*-* } } } */ +/* { dg-final { scan-assembler-times "rsb" 1 } } */ +/* { dg-final { scan-assembler-times "sbc" 1 } } */ +/* { dg-final { scan-assembler-times "mov" 0 } } */ +/* { dg-final { scan-assembler-times "rsc" 0 } } */ From patchwork Fri Oct 18 19:48:44 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: 1179634 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511322-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="HrV7xR4I"; dkim-atps=neutral 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 46vxdR5SmYz9sP7 for ; Sat, 19 Oct 2019 06:57:15 +1100 (AEDT) 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=kdfZmLSEaQGyyz5J O+rF4habNuqqQAmIDTjlxHn3QDcQkmorR+8aYLhqcTOR1e6spxuINEkKO/jCdhzZ c/IfUXsjFaeuCHY0rhr38LVXZgBe4IE05CbOva1SM+wunidGB1k0wApn1o8L23wX UCOO6X0kf67VKmZOnE2jFKDypPY= 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=yZK9VU4O4Eowb7QArPcDY7 sjQ3s=; b=HrV7xR4IMon+V66NnJ/kgnUhGP8uWeNcevKfZIwhAf/gk4uqZvlsM/ WtjJG3XHdQKTU2H9W+uM8H+/RCpXM4jvZZHeWmANd2x17T/tAxzqeb2adOEPoTL8 oTiy9quthC6QARfVVaWxBy1vsT4J7ICv/Qk9S5KGAfucMNSAlDBVs= Received: (qmail 114183 invoked by alias); 18 Oct 2019 19:55:43 -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 112640 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 autolearn=ham version=3.3.1 spammy= 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-00054r-7K for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:31 -0400 Received: from [217.140.110.172] (port=42752 helo=foss.arm.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1iLYLS-00054V-2A 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 5E14516A3; Fri, 18 Oct 2019 12:49:21 -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 DF48A3F6C4; Fri, 18 Oct 2019 12:49:20 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 13/29] [arm] Add alternative canonicalizations for subtract-with-carry + shift Date: Fri, 18 Oct 2019 20:48:44 +0100 Message-Id: <20191018194900.34795-14-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 adds a couple of alternative canonicalizations to allow combine to match a subtract-with-carry operation when one of the operands is shifted first. The most common case of this is when combining a sign-extend of one operand with a long-long value during subtraction. The RSC variant is only enabled for Arm, the SBC variant for any 32-bit compilation. * config/arm/arm.md (subsi3_carryin_shift_alt): New pattern. (rsbsi3_carryin_shift_alt): Likewise. --- gcc/config/arm/arm.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 74f417fbe4b..613f50ae5f0 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -1048,6 +1048,23 @@ (define_insn "*subsi3_carryin_shift" (const_string "alu_shift_reg")))] ) +(define_insn "*subsi3_carryin_shift_alt" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (minus:SI (minus:SI + (match_operand:SI 1 "s_register_operand" "r") + (match_operand:SI 5 "arm_borrow_operation" "")) + (match_operator:SI 2 "shift_operator" + [(match_operand:SI 3 "s_register_operand" "r") + (match_operand:SI 4 "reg_or_int_operand" "rM")])))] + "TARGET_32BIT" + "sbc%?\\t%0, %1, %3%S2" + [(set_attr "conds" "use") + (set_attr "predicable" "yes") + (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "") + (const_string "alu_shift_imm") + (const_string "alu_shift_reg")))] +) + (define_insn "*rsbsi3_carryin_shift" [(set (match_operand:SI 0 "s_register_operand" "=r") (minus:SI (minus:SI @@ -1065,6 +1082,23 @@ (define_insn "*rsbsi3_carryin_shift" (const_string "alu_shift_reg")))] ) +(define_insn "*rsbsi3_carryin_shift_alt" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (minus:SI (minus:SI + (match_operator:SI 2 "shift_operator" + [(match_operand:SI 3 "s_register_operand" "r") + (match_operand:SI 4 "reg_or_int_operand" "rM")]) + (match_operand:SI 5 "arm_borrow_operation" "")) + (match_operand:SI 1 "s_register_operand" "r")))] + "TARGET_ARM" + "rsc%?\\t%0, %1, %3%S2" + [(set_attr "conds" "use") + (set_attr "predicable" "yes") + (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "") + (const_string "alu_shift_imm") + (const_string "alu_shift_reg")))] +) + ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant. (define_split [(set (match_operand:SI 0 "s_register_operand" "") From patchwork Fri Oct 18 19:48:45 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: 1179648 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511336-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="Bw8roW20"; dkim-atps=neutral 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 46vxj20zKlz9sP7 for ; Sat, 19 Oct 2019 07:00:21 +1100 (AEDT) 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=EE31UDarfyQU7Zq8 kF7uMmPGQNunIyGMiwfJep0KVGeRm/4SHEltvR5qwucFVyE8wp1PKJeFP9em/ek5 M8Wn222j7wWWOHSUHKWIQjGfL08AOF0+i8GhcaDmnnXhtk5l2WK0k4dFudP1OWha XcSPUkweQI+MA7vMkKVxtdhFLrg= 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=dbk6QRmJRQZZh9tpH19S4a jw91o=; b=Bw8roW20aQVL4TiCsFPHC6/TrpRzwzIRcXSutqy6djXskWwm7hV3AN reaB6Fhg/37atsRWJT6LJoFrJ8VZtuauQjClwNnnVmSf78god0I6hZepPjvP9G6r iYP9txEV28BjlSVflL9hLRaXLcXGvKGlU68XGMe5DVIesvY8RRnxo= Received: (qmail 121980 invoked by alias); 18 Oct 2019 19:56:37 -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 115975 invoked by uid 89); 18 Oct 2019 19:55:52 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-19.3 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=flexible 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:50 +0000 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iLYLc-00059z-SH for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:42 -0400 Received: from [217.140.110.172] (port=42746 helo=foss.arm.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1iLYLc-000549-In for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:40 -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 11E9B16F2; 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 934FA3F6C4; Fri, 18 Oct 2019 12:49:21 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 14/29] [arm] Early split simple DImode equality comparisons Date: Fri, 18 Oct 2019 20:48:45 +0100 Message-Id: <20191018194900.34795-15-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 is the first step of early splitting all the DImode comparison operations. We start by factoring the DImode handling out of arm_gen_compare_reg into its own function. Simple DImode equality comparisions (such as equality with zero, or equality with a constant that is zero in one of the two word values that it comprises) can be done using a single subtract followed by an ORRS instruction. This avoids the need for conditional execution. For example, (r0 != 5) can be written as SUB Rt, R0, #5 ORRS Rt, Rt, R1 The ORRS is now expanded using an SImode pattern that already exists in the MD file and this gives the register allocator more freedom to select registers (consecutive pairs are no-longer required). Furthermore, we can then delete the arm_cmpdi_zero pattern as it is no-longer required. We use SUB for the value adjustment as this has a generally more flexible range of immediates than XOR and what's more has the opportunity to be relaxed in thumb2 to a 16-bit SUBS instruction. * config/arm/arm.c (arm_select_cc_mode): For DImode equality tests return CC_Zmode if comparing against a constant where one word is zero. (arm_gen_compare_reg): Split DImode handling to ... (arm_gen_dicompare_reg): ... here. Handle equality comparisons against simple constants. * config/arm/arm.md (arm_cmpdi_zero): Delete pattern. --- gcc/config/arm/arm.c | 87 +++++++++++++++++++++++++++++++++---------- gcc/config/arm/arm.md | 11 ------ 2 files changed, 68 insertions(+), 30 deletions(-) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index e33b6b14d28..64367b42332 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -15350,8 +15350,14 @@ arm_select_cc_mode (enum rtx_code op, rtx x, rtx y) case EQ: case NE: /* A DImode comparison against zero can be implemented by - or'ing the two halves together. */ - if (y == const0_rtx) + or'ing the two halves together. We can also handle + immediates where one word of that value is zero by + subtracting the non-zero word from the corresponding word + in the other register and then ORRing it with the other + word. */ + if (CONST_INT_P (y) + && ((UINTVAL (y) & 0xffffffff) == 0 + || (UINTVAL (y) >> 32) == 0)) return CC_Zmode; /* We can do an equality test in three Thumb instructions. */ @@ -15393,37 +15399,64 @@ arm_select_cc_mode (enum rtx_code op, rtx x, rtx y) return CCmode; } -/* X and Y are two things to compare using CODE. Emit the compare insn and - return the rtx for register 0 in the proper mode. FP means this is a - floating point compare: I don't think that it is needed on the arm. */ -rtx -arm_gen_compare_reg (enum rtx_code code, rtx x, rtx y, rtx scratch) +/* X and Y are two (DImode) things to compare for the condition CODE. Emit + the sequence of instructions needed to generate a suitable condition + code register. Return the CC register result. */ +static rtx +arm_gen_dicompare_reg (rtx_code code, rtx x, rtx y, rtx scratch) { - machine_mode mode; - rtx cc_reg; - int dimode_comparison = GET_MODE (x) == DImode || GET_MODE (y) == DImode; + /* We don't currently handle DImode in thumb1, but rely on libgcc. */ + gcc_assert (TARGET_32BIT); /* We might have X as a constant, Y as a register because of the predicates used for cmpdi. If so, force X to a register here. */ - if (dimode_comparison && !REG_P (x)) + if (!REG_P (x)) x = force_reg (DImode, x); - mode = SELECT_CC_MODE (code, x, y); - cc_reg = gen_rtx_REG (mode, CC_REGNUM); + machine_mode mode = SELECT_CC_MODE (code, x, y); + rtx cc_reg = gen_rtx_REG (mode, CC_REGNUM); - if (dimode_comparison - && mode != CC_CZmode) + if (mode != CC_CZmode) { rtx clobber, set; /* To compare two non-zero values for equality, XOR them and then compare against zero. Not used for ARM mode; there CC_CZmode is cheaper. */ - if (mode == CC_Zmode && y != const0_rtx) + if (mode == CC_Zmode) { - gcc_assert (!reload_completed); - x = expand_binop (DImode, xor_optab, x, y, NULL_RTX, 0, OPTAB_WIDEN); - y = const0_rtx; + mode = CC_NOOVmode; + PUT_MODE (cc_reg, mode); + if (y != const0_rtx) + { + gcc_assert (CONST_INT_P (y)); + rtx xlo, xhi, ylo, yhi; + arm_decompose_di_binop (x, y, &xlo, &xhi, &ylo, &yhi); + if (!scratch) + scratch = gen_reg_rtx (SImode); + if (ylo == const0_rtx) + { + yhi = GEN_INT (-INTVAL(yhi)); + if (!arm_add_operand (yhi, SImode)) + yhi = force_reg (SImode, yhi); + emit_insn (gen_addsi3 (scratch, xhi, yhi)); + y = xlo; + } + else + { + gcc_assert (yhi == const0_rtx); + ylo = GEN_INT (-INTVAL(ylo)); + if (!arm_add_operand (ylo, SImode)) + ylo = force_reg (SImode, ylo); + emit_insn (gen_addsi3 (scratch, xlo, ylo)); + y = xhi; + } + x = gen_rtx_IOR (SImode, scratch, y); + y = const0_rtx; + } + else + x = gen_rtx_IOR (SImode, gen_lowpart (SImode, x), + gen_highpart (SImode, x)); } /* A scratch register is required. */ @@ -15442,6 +15475,22 @@ arm_gen_compare_reg (enum rtx_code code, rtx x, rtx y, rtx scratch) return cc_reg; } +/* X and Y are two things to compare using CODE. Emit the compare insn and + return the rtx for register 0 in the proper mode. */ +rtx +arm_gen_compare_reg (rtx_code code, rtx x, rtx y, rtx scratch) +{ + if (GET_MODE (x) == DImode || GET_MODE (y) == DImode) + return arm_gen_dicompare_reg (code, x, y, scratch); + + machine_mode mode = SELECT_CC_MODE (code, x, y); + rtx cc_reg = gen_rtx_REG (mode, CC_REGNUM); + + emit_set_insn (cc_reg, gen_rtx_COMPARE (mode, x, y)); + + return cc_reg; +} + /* Generate a sequence of insns that will generate the correct return address mask depending on the physical architecture that the program is running on. */ diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 613f50ae5f0..a6b0c196c58 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -6518,17 +6518,6 @@ (define_insn_and_split "*arm_cmpdi_unsigned" (set_attr "type" "multiple")] ) -(define_insn "*arm_cmpdi_zero" - [(set (reg:CC_Z CC_REGNUM) - (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r") - (const_int 0))) - (clobber (match_scratch:SI 1 "=r"))] - "TARGET_32BIT" - "orrs%?\\t%1, %Q0, %R0" - [(set_attr "conds" "set") - (set_attr "type" "logics_reg")] -) - ; This insn allows redundant compares to be removed by cse, nothing should ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that ; is deleted later on. The match_dup will match the mode here, so that 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: 1179638 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511326-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="spCjyxt+"; dkim-atps=neutral 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 46vxfR1561z9sP7 for ; Sat, 19 Oct 2019 06:58:06 +1100 (AEDT) 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=XU0zi6pinn8f5aHL abLgLymBl4DbOykDQfmQQwxDlg1vZrUA3w2oB3pTDmYrGMXV5EJk8oMo+i6MEFX7 QPQtDcTDRFKTTXlXPAHJOWeHEMjOYG2vna47s+0L+yb8wb6DTd3KcIqD8+MKU5RO mNfAtzPpj5vbDQ5eWbZbMVQP2UI= 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=spCjyxt+Svu1R47etlXq/QFwYKn3DgFMDsYIgY8exzSCAag0++vbZm NR9pW97gh5dbsHX1+vM1cqvp+SZiBvTtzVS2f812Q//RIfqTlTN0WeXVrmlV/och HPdW9yTTFl1+0haOHvRsGldB1IqurJatPJ3BNzI6uuruRD+cZpeGI= 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], From patchwork Fri Oct 18 19:48:47 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: 1179625 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511314-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="Ei/po+TB"; dkim-atps=neutral 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 46vxVB18Djz9sPJ for ; Sat, 19 Oct 2019 06:50:57 +1100 (AEDT) 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=HPncca4fuKGun1+U N32rHNoH1QfKpq5rfQjsHvcG8vj698l0vZH2oVV3k5WgFJPppf8pBRUu6IT0dfIR bsbMCSXu3URM9alxj0JWlYr+KgCCtyQul5nXks37NpsXJYtnnQ5UpE7zSt7ibp3R BnzHI8Z1pH2nqP/G9IzUx0Pesp4= 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=9VWjUBXlwoFa0m7SubCTw2 U2By8=; b=Ei/po+TBOenQ7xwHnj9p4ymTZxZLhoNktv1Ppu/joJ8PCzbTMYRiok xEU1+o3f06g2SGopcG6uYMIjZmNYvthlPBJlEju7/jL+x54+/+HnOcUvLJl7ey5o rF4Zym+3yTtTU6w4VzAnNGMllB4G5h3BqxI5pHiwUHkTF8p40LyLQ= Received: (qmail 78553 invoked by alias); 18 Oct 2019 19:49:41 -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 78452 invoked by uid 89); 18 Oct 2019 19:49:40 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.5 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_PASS autolearn=ham version=3.3.1 spammy=sk:adjust_ X-HELO: foss.arm.com Received: from Unknown (HELO foss.arm.com) (217.140.110.172) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 18 Oct 2019 19:49:37 +0000 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 6DA9716F8; Fri, 18 Oct 2019 12:49:23 -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 EF3333F6C4; Fri, 18 Oct 2019 12:49:22 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 16/29] [arm] early split most DImode comparison operations. Date: Fri, 18 Oct 2019 20:48:47 +0100 Message-Id: <20191018194900.34795-17-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 This patch does most of the work for early splitting the DImode comparisons. We now handle EQ, NE, LT, GE, LTU and GEU during early expansion, in addition to EQ and NE, for which the expansion has now been reworked to use a standard conditional-compare pattern already in the back-end. To handle this we introduce two new condition flag modes that are used when comparing the upper words of decomposed DImode values: one for signed, and one for unsigned comparisons. CC_Bmode (B for Borrow) is essentially the inverse of CC_Cmode and is used when the carry flag is set by a subtraction of unsigned values. * config/arm/arm-modes.def (CC_NV, CC_B): New CC modes. * config/arm/arm.c (arm_select_cc_mode): Recognize constructs that need these modes. (arm_gen_dicompare_reg): New code to early expand the sub-operations of EQ, NE, LT, GE, LTU and GEU. * config/arm/iterators.md (CC_EXTEND): New code attribute. * config/arm/predicates.md (arm_adcimm_operand): New predicate.. * config/arm/arm.md (cmpsi3_carryin_out): New pattern. (cmpsi3_imm_carryin_out): Likewise. (cmpsi3_0_carryin_out): Likewise. --- gcc/config/arm/arm-modes.def | 6 + gcc/config/arm/arm.c | 220 ++++++++++++++++++++++++++++++++++- gcc/config/arm/arm.md | 45 +++++++ gcc/config/arm/iterators.md | 4 + gcc/config/arm/predicates.md | 6 + 5 files changed, 278 insertions(+), 3 deletions(-) diff --git a/gcc/config/arm/arm-modes.def b/gcc/config/arm/arm-modes.def index 4fa7f1b43e5..65cddf68cdb 100644 --- a/gcc/config/arm/arm-modes.def +++ b/gcc/config/arm/arm-modes.def @@ -34,12 +34,16 @@ ADJUST_FLOAT_FORMAT (HF, ((arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE) CC_Cmode should be used if only the C flag is set correctly, after an addition. CC_Nmode should be used if only the N (sign) flag is set correctly + CC_NVmode should be used if only the N and V bits are set correctly, + (used for signed comparisons when the carry is propagated in). CC_CZmode should be used if only the C and Z flags are correct (used for DImode unsigned comparisons). CC_RSBmode should be used where the comparison is set by an RSB immediate, or NEG instruction. The form of the comparison for (const - reg) will be (COMPARE (not (reg)) (~const)). CC_NCVmode should be used if only the N, C, and V flags are correct + CC_Bmode should be used if only the C flag is correct after a subtract + (eg after an unsigned borrow with carry-in propagation). (used for DImode signed comparisons). CCmode should be used otherwise. */ @@ -47,6 +51,7 @@ CC_MODE (CC_NOOV); CC_MODE (CC_Z); CC_MODE (CC_CZ); CC_MODE (CC_NCV); +CC_MODE (CC_NV); CC_MODE (CC_SWP); CC_MODE (CC_RSB); CC_MODE (CCFP); @@ -62,6 +67,7 @@ CC_MODE (CC_DLTU); CC_MODE (CC_DGEU); CC_MODE (CC_DGTU); CC_MODE (CC_C); +CC_MODE (CC_B); CC_MODE (CC_N); CC_MODE (CC_V); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index ddfe4335169..99c8bd79d30 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -15348,6 +15348,22 @@ arm_select_cc_mode (enum rtx_code op, rtx x, rtx y) && (rtx_equal_p (XEXP (x, 0), y) || rtx_equal_p (XEXP (x, 1), y))) return CC_Cmode; + if (GET_MODE (x) == DImode + && (op == GE || op == LT) + && GET_CODE (x) == SIGN_EXTEND + && ((GET_CODE (y) == PLUS + && arm_borrow_operation (XEXP (y, 0), DImode)) + || arm_borrow_operation (y, DImode))) + return CC_NVmode; + + if (GET_MODE (x) == DImode + && (op == GEU || op == LTU) + && GET_CODE (x) == ZERO_EXTEND + && ((GET_CODE (y) == PLUS + && arm_borrow_operation (XEXP (y, 0), DImode)) + || arm_borrow_operation (y, DImode))) + return CC_Bmode; + if (GET_MODE (x) == DImode || GET_MODE (y) == DImode) { switch (op) @@ -15410,16 +15426,198 @@ arm_select_cc_mode (enum rtx_code op, rtx x, rtx y) static rtx arm_gen_dicompare_reg (rtx_code code, rtx x, rtx y, rtx scratch) { - /* We don't currently handle DImode in thumb1, but rely on libgcc. */ + machine_mode mode; + rtx cc_reg; + + /* We don't currently handle DImode in thumb1, but rely on libgcc. */ gcc_assert (TARGET_32BIT); + rtx x_lo = simplify_gen_subreg (SImode, x, DImode, + subreg_lowpart_offset (SImode, DImode)); + rtx x_hi = simplify_gen_subreg (SImode, x, DImode, + subreg_highpart_offset (SImode, DImode)); + rtx y_lo = simplify_gen_subreg (SImode, y, DImode, + subreg_lowpart_offset (SImode, DImode)); + rtx y_hi = simplify_gen_subreg (SImode, y, DImode, + subreg_highpart_offset (SImode, DImode)); + switch (code) + { + case EQ: + case NE: + { + /* We should never have X as a const_int in this case. */ + gcc_assert (!CONST_INT_P (x)); + + if (y_lo == const0_rtx || y_hi == const0_rtx) + { + if (y_lo != const0_rtx) + { + rtx scratch2 = scratch ? scratch : gen_reg_rtx (SImode); + + gcc_assert (y_hi == const0_rtx); + y_lo = gen_int_mode (-INTVAL (y_lo), SImode); + if (!arm_add_operand (y_lo, SImode)) + y_lo = force_reg (SImode, y_lo); + emit_insn (gen_addsi3 (scratch2, x_lo, y_lo)); + x_lo = scratch2; + } + else if (y_hi != const0_rtx) + { + rtx scratch2 = scratch ? scratch : gen_reg_rtx (SImode); + + y_hi = gen_int_mode (-INTVAL (y_hi), SImode); + if (!arm_add_operand (y_hi, SImode)) + y_hi = force_reg (SImode, y_hi); + emit_insn (gen_addsi3 (scratch2, x_hi, y_hi)); + x_hi = scratch2; + } + + if (!scratch) + { + gcc_assert (!reload_completed); + scratch = gen_rtx_SCRATCH (SImode); + } + + rtx clobber = gen_rtx_CLOBBER (VOIDmode, scratch); + cc_reg = gen_rtx_REG (CC_NOOVmode, CC_REGNUM); + + rtx set + = gen_rtx_SET (cc_reg, + gen_rtx_COMPARE (CC_NOOVmode, + gen_rtx_IOR (SImode, x_lo, x_hi), + const0_rtx)); + emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, + clobber))); + return cc_reg; + } + + if (!arm_add_operand (y_lo, SImode)) + y_lo = force_reg (SImode, y_lo); + + if (!arm_add_operand (y_hi, SImode)) + y_hi = force_reg (SImode, y_hi); + + rtx cmp1 = gen_rtx_NE (SImode, x_lo, y_lo); + rtx cmp2 = gen_rtx_NE (SImode, x_hi, y_hi); + rtx conjunction = gen_rtx_IOR (SImode, cmp1, cmp2); + mode = SELECT_CC_MODE (code, conjunction, const0_rtx); + cc_reg = gen_rtx_REG (mode, CC_REGNUM); + + emit_insn (gen_rtx_SET (cc_reg, + gen_rtx_COMPARE (VOIDmode, conjunction, + const0_rtx))); + return cc_reg; + } + + case LT: + case GE: + { + if (y_lo == const0_rtx) + { + /* If the low word of y is 0, then this is simply a normal + compare of the upper words. */ + if (!arm_add_operand (y_hi, SImode)) + y_hi = force_reg (SImode, y_hi); + + return arm_gen_compare_reg (code, x_hi, y_hi, NULL_RTX); + } + + if (!arm_add_operand (y_lo, SImode)) + y_lo = force_reg (SImode, y_lo); + + /* Just for now. */ + if (!register_operand (x_lo, SImode)) + x_lo = force_reg (SImode, x_lo); + + rtx cmp1 + = gen_rtx_LTU (DImode, + arm_gen_compare_reg (LTU, x_lo, y_lo, NULL_RTX), + const0_rtx); + + if (!scratch) + scratch = gen_rtx_SCRATCH (SImode); + if (!arm_not_operand (y_hi, SImode)) + y_hi = force_reg (SImode, y_hi); + + /* Just for now. */ + if (!register_operand (x_hi, SImode)) + x_hi = force_reg (SImode, x_hi); + + rtx_insn *insn; + if (y_hi == const0_rtx) + insn = emit_insn (gen_cmpsi3_0_carryin_CC_NVout (scratch, x_hi, + cmp1)); + else if (CONST_INT_P (y_hi)) + insn = emit_insn (gen_cmpsi3_imm_carryin_CC_NVout (scratch, x_hi, + y_hi, cmp1)); + else + insn = emit_insn (gen_cmpsi3_carryin_CC_NVout (scratch, x_hi, y_hi, + cmp1)); + return SET_DEST (single_set (insn)); + } + + case LTU: + case GEU: + { + if (y_lo == const0_rtx) + { + /* If the low word of y is 0, then this is simply a normal + compare of the upper words. */ + if (!arm_add_operand (y_hi, SImode)) + y_hi = force_reg (SImode, y_hi); + + return arm_gen_compare_reg (code, x_hi, y_hi, NULL_RTX); + } + + if (!arm_add_operand (y_lo, SImode)) + y_lo = force_reg (SImode, y_lo); + + /* Just for now. */ + if (!register_operand (x_lo, SImode)) + x_lo = force_reg (SImode, x_lo); + + rtx cmp1 + = gen_rtx_LTU (DImode, + arm_gen_compare_reg (LTU, x_lo, y_lo, NULL_RTX), + const0_rtx); + + if (!scratch) + scratch = gen_rtx_SCRATCH (SImode); + if (!arm_not_operand (y_hi, SImode)) + y_hi = force_reg (SImode, y_hi); + + /* Just for now. */ + if (!register_operand (x_hi, SImode)) + x_hi = force_reg (SImode, x_hi); + + rtx_insn *insn; + if (y_hi == const0_rtx) + insn = emit_insn (gen_cmpsi3_0_carryin_CC_Bout (scratch, x_hi, + cmp1)); + else if (CONST_INT_P (y_hi)) + { + /* Constant is viewed as unsigned when zero-extended. */ + y_hi = GEN_INT (UINTVAL (y_hi) & 0xffffffffULL); + insn = emit_insn (gen_cmpsi3_imm_carryin_CC_Bout (scratch, x_hi, + y_hi, cmp1)); + } + else + insn = emit_insn (gen_cmpsi3_carryin_CC_Bout (scratch, x_hi, y_hi, + cmp1)); + return SET_DEST (single_set (insn)); + } + + default: + break; + } + /* We might have X as a constant, Y as a register because of the predicates used for cmpdi. If so, force X to a register here. */ if (!REG_P (x)) x = force_reg (DImode, x); - machine_mode mode = SELECT_CC_MODE (code, x, y); - rtx cc_reg = gen_rtx_REG (mode, CC_REGNUM); + mode = SELECT_CC_MODE (code, x, y); + cc_reg = gen_rtx_REG (mode, CC_REGNUM); if (mode != CC_CZmode) { @@ -23803,6 +24001,22 @@ maybe_get_arm_condition_code (rtx comparison) default: return ARM_NV; } + case E_CC_NVmode: + switch (comp_code) + { + case GE: return ARM_GE; + case LT: return ARM_LT; + default: return ARM_NV; + } + + case E_CC_Bmode: + switch (comp_code) + { + case GEU: return ARM_CS; + case LTU: return ARM_CC; + default: return ARM_NV; + } + case E_CC_Vmode: switch (comp_code) { diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 9d8b137651f..f0ff4dda396 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -1009,6 +1009,51 @@ (define_insn "subsi3_carryin" (set_attr "type" "adc_reg,adc_imm,alu_shift_imm")] ) +(define_insn "cmpsi3_carryin_out" + [(set (reg: CC_REGNUM) + (compare: + (SE:DI (match_operand:SI 1 "s_register_operand" "0,r")) + (plus:DI (match_operand:DI 3 "arm_borrow_operation" "") + (SE:DI (match_operand:SI 2 "s_register_operand" "l,r"))))) + (clobber (match_scratch:SI 0 "=l,r"))] + "TARGET_32BIT" + "sbcs\\t%0, %1, %2" + [(set_attr "conds" "set") + (set_attr "arch" "t2,*") + (set_attr "length" "2,4") + (set_attr "type" "adc_reg")] +) + +;; Similar to the above, but handling a constant which has a different +;; canonicalization. +(define_insn "cmpsi3_imm_carryin_out" + [(set (reg: CC_REGNUM) + (compare: + (SE:DI (match_operand:SI 1 "s_register_operand" "r,r")) + (plus:DI (match_operand:DI 3 "arm_borrow_operation" "") + (match_operand:DI 2 "arm_adcimm_operand" "I,K")))) + (clobber (match_scratch:SI 0 "=l,r"))] + "TARGET_32BIT" + "@ + sbcs\\t%0, %1, %2 + adcs\\t%0, %1, #%B2" + [(set_attr "conds" "set") + (set_attr "type" "adc_imm")] +) + +;; Further canonicalization when the constant is zero. +(define_insn "cmpsi3_0_carryin_out" + [(set (reg: CC_REGNUM) + (compare: + (SE:DI (match_operand:SI 1 "s_register_operand" "r,r")) + (match_operand:DI 2 "arm_borrow_operation" ""))) + (clobber (match_scratch:SI 0 "=l,r"))] + "TARGET_32BIT" + "sbcs\\t%0, %1, #0" + [(set_attr "conds" "set") + (set_attr "type" "adc_imm")] +) + (define_insn "*subsi3_carryin_const" [(set (match_operand:SI 0 "s_register_operand" "=r") (minus:SI (plus:SI diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md index 77e1645083f..5f1c833ad80 100644 --- a/gcc/config/arm/iterators.md +++ b/gcc/config/arm/iterators.md @@ -792,6 +792,10 @@ (define_mode_attr vsi2qi [(V2SI "v8qi") (V4SI "v16qi")]) ;; Code attributes ;;---------------------------------------------------------------------------- +;; Determine the mode of a 'wide compare', ie where the carry flag is +;; propagated into the comparison. +(define_code_attr CC_EXTEND [(sign_extend "CC_NV") (zero_extend "CC_B")]) + ;; Assembler mnemonics for vqh_ops and vqhs_ops iterators. (define_code_attr VQH_mnem [(plus "vadd") (smin "vmin") (smax "vmax") (umin "vmin") (umax "vmax")]) diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md index ed7495b69fc..d9470df8093 100644 --- a/gcc/config/arm/predicates.md +++ b/gcc/config/arm/predicates.md @@ -229,6 +229,12 @@ (define_predicate "arm_not_operand" (ior (match_operand 0 "arm_rhs_operand") (match_operand 0 "arm_not_immediate_operand"))) +;; A constant that can be used with ADC(SBC) or SBC(ADC) when bit-wise +;; inverted. Similar to arm_not_operand, but excludes registers. +(define_predicate "arm_adcimm_operand" + (ior (match_operand 0 "arm_immediate_operand") + (match_operand 0 "arm_not_immediate_operand"))) + (define_predicate "arm_di_operand" (ior (match_operand 0 "s_register_operand") (match_operand 0 "arm_immediate_di_operand"))) From patchwork Fri Oct 18 19:48:48 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: 1179636 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511324-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="xC0ui0jj"; dkim-atps=neutral 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 46vxdx0HpPz9sP7 for ; Sat, 19 Oct 2019 06:57:40 +1100 (AEDT) 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=kKZupwbbIxq9IYkt 0Kzo4OS1pn+jAE88Mw2LPP9Kni5dUYCJteHTtAE+XH5nKmoHpVH3/CXRCX0njmNw z1iJyoK79FIagrU9EFyUuZz1XVOFPxWqD0o3XQXdKxglSXf06JMsL6gQ8ISpfU/4 HKeAfU5IZN5cABhdSPblzvkqZWg= 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=s3L8B4ch5HlmqIfqaZZS5w 153W4=; b=xC0ui0jjl+oKW8gdtLh+mEfAcpSyVf2L3KCLEmdVYa9DBbwlaQ0HSJ xLBQnrcEjkQsl3rmG8lF3TOEXiX7XEMSs3QC0b+tjE2AOnPaX7u0zsiB1MlK88nL sYR5I35ZcihVvDcGT319fqT8v4TbW/3Q4/Wpta8V901VamNEQ6dTE= Received: (qmail 114929 invoked by alias); 18 Oct 2019 19:55: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 113307 invoked by uid 89); 18 Oct 2019 19:55:41 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.9 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=swapped 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-00055e-NK for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:32 -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 1iLYLS-00053X-Es 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 213631715; Fri, 18 Oct 2019 12:49:24 -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 A2CC23F6C4; Fri, 18 Oct 2019 12:49:23 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 17/29] [arm] Handle some constant comparisons using rsbs+rscs Date: Fri, 18 Oct 2019 20:48:48 +0100 Message-Id: <20191018194900.34795-18-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 a small number of cases it is preferable to handle comparisons with constants using the sequence RSBS tmp, Xlo, constlo RSCS tmp, Xhi, consthi which allows us to handle a small number of LE/GT/LEU/GEU cases when changing the code to use LT/GE/LTU/GEU would make the constant more expensive. Sadly, we cannot do this on Thumb, since we need RSC, so we now always use the incremented constant in that case since normally that still works out cheaper than forcing the entire constant into a register. Further investigation has also shown that the canonicalization of a reverse subtract and compare is valid for signed as well as unsigned value, so we relax the restriction on selecting CC_RSBmode to allow all types of compare. * config/arm/arm.c (arm_const_double_prefer_rsbs_rsc): New function. (arm_canonicalize_comparison): For GT/LE/GTU/GEU, use the constant unchanged only if that will be cheaper. (arm_select_cc_mode): Recognize a swapped comparison that will be regenerated using RSBS or RSCS. Relax restriction on selecting CC_RSBmode. (arm_gen_dicompare_reg): Handle LE/GT/LEU/GEU comparisons against a constant. (arm_gen_compare_reg): Handle compare (CONST, X) when the mode is CC_RSBmode. (maybe_get_arm_condition_code): CC_RSBmode now returns the same codes as CCmode. * config/arm/arm.md (rsb_imm_compare_scratch): New pattern. (rscsi3_out_scratch): New pattern. --- gcc/config/arm/arm.c | 153 +++++++++++++++++++++++++++++------------- gcc/config/arm/arm.md | 27 ++++++++ 2 files changed, 134 insertions(+), 46 deletions(-) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 99c8bd79d30..299dce638c2 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -5355,6 +5355,21 @@ arm_gen_constant (enum rtx_code code, machine_mode mode, rtx cond, return insns; } +/* Return TRUE if op is a constant where both the low and top words are + suitable for RSB/RSC instructions. This is never true for Thumb, since + we do not have RSC in that case. */ +static bool +arm_const_double_prefer_rsbs_rsc (rtx op) +{ + /* Thumb lacks RSC, so we never prefer that sequence. */ + if (TARGET_THUMB || !CONST_INT_P (op)) + return false; + HOST_WIDE_INT hi, lo; + lo = UINTVAL (op) & 0xffffffffULL; + hi = UINTVAL (op) >> 32; + return const_ok_for_arm (lo) && const_ok_for_arm (hi); +} + /* Canonicalize a comparison so that we are more likely to recognize it. This can be done for a few constant compares, where we can make the immediate value easier to load. */ @@ -5380,8 +5395,7 @@ arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1, { if (*code == GT || *code == LE - || ((!TARGET_ARM || CONST_INT_P (*op1)) - && (*code == GTU || *code == LEU))) + || *code == GTU || *code == LEU) { /* Missing comparison. First try to use an available comparison. */ @@ -5392,10 +5406,13 @@ arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1, { case GT: case LE: - if (i != maxval - && (!arm_const_double_by_immediates (*op1) - || arm_const_double_by_immediates (GEN_INT (i + 1)))) + if (i != maxval) { + /* Try to convert to GE/LT, unless that would be more + expensive. */ + if (!arm_const_double_by_immediates (GEN_INT (i + 1)) + && arm_const_double_prefer_rsbs_rsc (*op1)) + return; *op1 = GEN_INT (i + 1); *code = *code == GT ? GE : LT; return; @@ -5404,10 +5421,13 @@ arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1, case GTU: case LEU: - if (i != ~((unsigned HOST_WIDE_INT) 0) - && (!arm_const_double_by_immediates (*op1) - || arm_const_double_by_immediates (GEN_INT (i + 1)))) + if (i != ~((unsigned HOST_WIDE_INT) 0)) { + /* Try to convert to GEU/LTU, unless that would + be more expensive. */ + if (!arm_const_double_by_immediates (GEN_INT (i + 1)) + && arm_const_double_prefer_rsbs_rsc (*op1)) + return; *op1 = GEN_INT (i + 1); *code = *code == GTU ? GEU : LTU; return; @@ -5419,7 +5439,6 @@ arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1, } } - /* If that did not work, reverse the condition. */ if (!op0_preserve_value) { std::swap (*op0, *op1); @@ -15251,6 +15270,28 @@ arm_select_cc_mode (enum rtx_code op, rtx x, rtx y) || GET_CODE (x) == ROTATERT)) return CC_SWPmode; + /* A widened compare of the sum of a value plus a carry against a + constant. This is a representation of RSC. We want to swap the + result of the comparison at output. Not valid if the Z bit is + needed. */ + if (GET_MODE (x) == DImode + && GET_CODE (x) == PLUS + && arm_borrow_operation (XEXP (x, 1), DImode) + && CONST_INT_P (y) + && ((GET_CODE (XEXP (x, 0)) == SIGN_EXTEND + && (op == LE || op == GT)) + || (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND + && (op == LEU || op == GTU)))) + return CC_SWPmode; + + /* If X is a constant we want to use CC_RSBmode. This is + non-canonical, but arm_gen_compare_reg uses this to generate the + correct canonical form. */ + if (GET_MODE (y) == SImode + && (REG_P (y) || GET_CODE (y) == SUBREG) + && CONST_INT_P (x)) + return CC_RSBmode; + /* This operation is performed swapped, but since we only rely on the Z flag we don't need an additional mode. */ if (GET_MODE (y) == SImode @@ -15329,15 +15370,13 @@ arm_select_cc_mode (enum rtx_code op, rtx x, rtx y) || (TARGET_32BIT && GET_CODE (x) == ZERO_EXTRACT))) return CC_NOOVmode; - /* An unsigned comparison of ~reg with a const is really a special + /* A comparison of ~reg with a const is really a special canoncialization of compare (~const, reg), which is a reverse subtract operation. We may not get here if CONST is 0, but that doesn't matter because ~0 isn't a valid immediate for RSB. */ if (GET_MODE (x) == SImode && GET_CODE (x) == NOT - && CONST_INT_P (y) - && (op == EQ || op == NE - || op == LTU || op == LEU || op == GEU || op == GTU)) + && CONST_INT_P (y)) return CC_RSBmode; if (GET_MODE (x) == QImode && (op == EQ || op == NE)) @@ -15431,6 +15470,7 @@ arm_gen_dicompare_reg (rtx_code code, rtx x, rtx y, rtx scratch) /* We don't currently handle DImode in thumb1, but rely on libgcc. */ gcc_assert (TARGET_32BIT); + gcc_assert (!CONST_INT_P (x)); rtx x_lo = simplify_gen_subreg (SImode, x, DImode, subreg_lowpart_offset (SImode, DImode)); @@ -15445,9 +15485,6 @@ arm_gen_dicompare_reg (rtx_code code, rtx x, rtx y, rtx scratch) case EQ: case NE: { - /* We should never have X as a const_int in this case. */ - gcc_assert (!CONST_INT_P (x)); - if (y_lo == const0_rtx || y_hi == const0_rtx) { if (y_lo != const0_rtx) @@ -15525,10 +15562,6 @@ arm_gen_dicompare_reg (rtx_code code, rtx x, rtx y, rtx scratch) if (!arm_add_operand (y_lo, SImode)) y_lo = force_reg (SImode, y_lo); - /* Just for now. */ - if (!register_operand (x_lo, SImode)) - x_lo = force_reg (SImode, x_lo); - rtx cmp1 = gen_rtx_LTU (DImode, arm_gen_compare_reg (LTU, x_lo, y_lo, NULL_RTX), @@ -15536,13 +15569,10 @@ arm_gen_dicompare_reg (rtx_code code, rtx x, rtx y, rtx scratch) if (!scratch) scratch = gen_rtx_SCRATCH (SImode); + if (!arm_not_operand (y_hi, SImode)) y_hi = force_reg (SImode, y_hi); - /* Just for now. */ - if (!register_operand (x_hi, SImode)) - x_hi = force_reg (SImode, x_hi); - rtx_insn *insn; if (y_hi == const0_rtx) insn = emit_insn (gen_cmpsi3_0_carryin_CC_NVout (scratch, x_hi, @@ -15556,6 +15586,27 @@ arm_gen_dicompare_reg (rtx_code code, rtx x, rtx y, rtx scratch) return SET_DEST (single_set (insn)); } + case LE: + case GT: + { + /* During expansion, we only expect to get here if y is a + constant that we want to handle, otherwise we should have + swapped the operands already. */ + gcc_assert (arm_const_double_prefer_rsbs_rsc (y)); + + if (!const_ok_for_arm (INTVAL (y_lo))) + y_lo = force_reg (SImode, y_lo); + + /* Perform a reverse subtract and compare. */ + rtx cmp1 + = gen_rtx_LTU (DImode, + arm_gen_compare_reg (LTU, y_lo, x_lo, scratch), + const0_rtx); + rtx_insn *insn = emit_insn (gen_rscsi3_CC_NVout_scratch (scratch, y_hi, + x_hi, cmp1)); + return SET_DEST (single_set (insn)); + } + case LTU: case GEU: { @@ -15572,10 +15623,6 @@ arm_gen_dicompare_reg (rtx_code code, rtx x, rtx y, rtx scratch) if (!arm_add_operand (y_lo, SImode)) y_lo = force_reg (SImode, y_lo); - /* Just for now. */ - if (!register_operand (x_lo, SImode)) - x_lo = force_reg (SImode, x_lo); - rtx cmp1 = gen_rtx_LTU (DImode, arm_gen_compare_reg (LTU, x_lo, y_lo, NULL_RTX), @@ -15586,10 +15633,6 @@ arm_gen_dicompare_reg (rtx_code code, rtx x, rtx y, rtx scratch) if (!arm_not_operand (y_hi, SImode)) y_hi = force_reg (SImode, y_hi); - /* Just for now. */ - if (!register_operand (x_hi, SImode)) - x_hi = force_reg (SImode, x_hi); - rtx_insn *insn; if (y_hi == const0_rtx) insn = emit_insn (gen_cmpsi3_0_carryin_CC_Bout (scratch, x_hi, @@ -15607,6 +15650,28 @@ arm_gen_dicompare_reg (rtx_code code, rtx x, rtx y, rtx scratch) return SET_DEST (single_set (insn)); } + case LEU: + case GTU: + { + /* During expansion, we only expect to get here if y is a + constant that we want to handle, otherwise we should have + swapped the operands already. */ + gcc_assert (arm_const_double_prefer_rsbs_rsc (y)); + + if (!const_ok_for_arm (INTVAL (y_lo))) + y_lo = force_reg (SImode, y_lo); + + /* Perform a reverse subtract and compare. */ + rtx cmp1 + = gen_rtx_LTU (DImode, + arm_gen_compare_reg (LTU, y_lo, x_lo, scratch), + const0_rtx); + y_hi = GEN_INT (0xffffffff & UINTVAL (y_hi)); + rtx_insn *insn = emit_insn (gen_rscsi3_CC_Bout_scratch (scratch, y_hi, + x_hi, cmp1)); + return SET_DEST (single_set (insn)); + } + default: break; } @@ -15695,8 +15760,15 @@ arm_gen_compare_reg (rtx_code code, rtx x, rtx y, rtx scratch) machine_mode mode = SELECT_CC_MODE (code, x, y); rtx cc_reg = gen_rtx_REG (mode, CC_REGNUM); - - emit_set_insn (cc_reg, gen_rtx_COMPARE (mode, x, y)); + if (mode == CC_RSBmode) + { + if (!scratch) + scratch = gen_rtx_SCRATCH (SImode); + emit_insn (gen_rsb_imm_compare_scratch (scratch, + GEN_INT (~UINTVAL (x)), y)); + } + else + emit_set_insn (cc_reg, gen_rtx_COMPARE (mode, x, y)); return cc_reg; } @@ -24025,19 +24097,8 @@ maybe_get_arm_condition_code (rtx comparison) default: return ARM_NV; } - case E_CC_RSBmode: - switch (comp_code) - { - case NE: return ARM_NE; - case EQ: return ARM_EQ; - case GEU: return ARM_CS; - case GTU: return ARM_HI; - case LEU: return ARM_LS; - case LTU: return ARM_CC; - default: return ARM_NV; - } - case E_CCmode: + case E_CC_RSBmode: switch (comp_code) { case NE: return ARM_NE; diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index f0ff4dda396..8607c6f95da 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -1363,6 +1363,33 @@ (define_insn "rsb_imm_compare" (set_attr "type" "alus_imm")] ) +;; Similarly, but the result is unused. +(define_insn "rsb_imm_compare_scratch" + [(set (reg:CC_RSB CC_REGNUM) + (compare:CC_RSB (not:SI (match_operand:SI 2 "s_register_operand" "r")) + (match_operand 1 "arm_not_immediate_operand" "K"))) + (clobber (match_scratch:SI 0 "=r"))] + "TARGET_32BIT" + "rsbs\\t%0, %2, #%B1" + [(set_attr "conds" "set") + (set_attr "type" "alus_imm")] +) + +;; Compare the sum of a value plus a carry against a constant. Uses +;; RSC, so the result is swapped. Only available on Arm +(define_insn "rscsi3_out_scratch" + [(set (reg:CC_SWP CC_REGNUM) + (compare:CC_SWP + (plus:DI (SE:DI (match_operand:SI 2 "s_register_operand" "r")) + (match_operand:DI 3 "arm_borrow_operation" "")) + (match_operand 1 "arm_immediate_operand" "I"))) + (clobber (match_scratch:SI 0 "=r"))] + "TARGET_ARM" + "rscs\\t%0, %2, %1" + [(set_attr "conds" "set") + (set_attr "type" "alus_imm")] +) + (define_expand "subsf3" [(set (match_operand:SF 0 "s_register_operand") (minus:SF (match_operand:SF 1 "s_register_operand") From patchwork Fri Oct 18 19:48:49 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: 1179646 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511334-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="bH6Wihip"; dkim-atps=neutral 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 46vxhV5vSsz9sPJ for ; Sat, 19 Oct 2019 06:59:54 +1100 (AEDT) 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=Rua9e20AbPEuvkFK udPkjof2Bh+tHWUNYTXzbhgFLcinf0bI/bqn8YNaJMPPWe/PnpV2L8e3yTdyXbc0 VRZKDHX+CZry8AkFqni22+M1R0P2wvKl/26A/4+dpPlR3jk82LJlBqtHeBin6sgN kEBHIhCzJOF/P+xVzf7gBFVJJEg= 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=o9Y0q/SqioMF/T6POJRMJM JtoX4=; b=bH6WihipuFc3+U8WWmqUFvQfREanDT1h7yk00Icut4NTrrDjK96Er6 i2yf3m6VSym9qVHIbs4I1ArmwVR5MacchdEfZVNCZVTraU8D/9g9aprIc5CzjzEm GkpaDRUA68QKsI6Qfz64JD8rXMZ8V3LL+1nb+s7SKYyRzjQONuRRg= Received: (qmail 119812 invoked by alias); 18 Oct 2019 19:56:22 -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 115603 invoked by uid 89); 18 Oct 2019 19:55:49 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-19.2 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= 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:46 +0000 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iLYLd-0005AJ-4m for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:42 -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 1iLYLc-00053X-ST for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:41 -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 C93C61756; Fri, 18 Oct 2019 12:49:24 -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 5693D3F6C4; Fri, 18 Oct 2019 12:49:24 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 18/29] [arm] Cleanup dead code - old support for DImode comparisons Date: Fri, 18 Oct 2019 20:48:49 +0100 Message-Id: <20191018194900.34795-19-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 Now that all the major patterns for DImode have been converted to early expansion, we can safely clean up some dead code for the old way of handling DImode. * config/arm/arm-modes.def (CC_NCV, CC_CZ): Delete CC modes. * config/arm/arm.c (arm_select_cc_mode): Remove old selection code for DImode operands. (arm_gen_dicompare_reg): Remove unreachable expansion code. (maybe_get_arm_condition_code): Remove support for CC_CZmode and CC_NCVmode. * config/arm/arm.md (arm_cmpdi_insn): Delete. (arm_cmpdi_unsigned): Delete. --- gcc/config/arm/arm-modes.def | 5 -- gcc/config/arm/arm.c | 147 +---------------------------------- gcc/config/arm/arm.md | 45 ----------- 3 files changed, 1 insertion(+), 196 deletions(-) diff --git a/gcc/config/arm/arm-modes.def b/gcc/config/arm/arm-modes.def index 65cddf68cdb..f0eb8415b93 100644 --- a/gcc/config/arm/arm-modes.def +++ b/gcc/config/arm/arm-modes.def @@ -36,12 +36,9 @@ ADJUST_FLOAT_FORMAT (HF, ((arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE) CC_Nmode should be used if only the N (sign) flag is set correctly CC_NVmode should be used if only the N and V bits are set correctly, (used for signed comparisons when the carry is propagated in). - CC_CZmode should be used if only the C and Z flags are correct - (used for DImode unsigned comparisons). CC_RSBmode should be used where the comparison is set by an RSB immediate, or NEG instruction. The form of the comparison for (const - reg) will be (COMPARE (not (reg)) (~const)). - CC_NCVmode should be used if only the N, C, and V flags are correct CC_Bmode should be used if only the C flag is correct after a subtract (eg after an unsigned borrow with carry-in propagation). (used for DImode signed comparisons). @@ -49,8 +46,6 @@ ADJUST_FLOAT_FORMAT (HF, ((arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE) CC_MODE (CC_NOOV); CC_MODE (CC_Z); -CC_MODE (CC_CZ); -CC_MODE (CC_NCV); CC_MODE (CC_NV); CC_MODE (CC_SWP); CC_MODE (CC_RSB); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 299dce638c2..6da2a368d9f 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -15403,56 +15403,6 @@ arm_select_cc_mode (enum rtx_code op, rtx x, rtx y) || arm_borrow_operation (y, DImode))) return CC_Bmode; - if (GET_MODE (x) == DImode || GET_MODE (y) == DImode) - { - switch (op) - { - case EQ: - case NE: - /* A DImode comparison against zero can be implemented by - or'ing the two halves together. We can also handle - immediates where one word of that value is zero by - subtracting the non-zero word from the corresponding word - in the other register and then ORRing it with the other - word. */ - if (CONST_INT_P (y) - && ((UINTVAL (y) & 0xffffffff) == 0 - || (UINTVAL (y) >> 32) == 0)) - return CC_Zmode; - - /* We can do an equality test in three Thumb instructions. */ - if (!TARGET_32BIT) - return CC_Zmode; - - /* FALLTHROUGH */ - - case LTU: - case LEU: - case GTU: - case GEU: - /* DImode unsigned comparisons can be implemented by cmp + - cmpeq without a scratch register. Not worth doing in - Thumb-2. */ - if (TARGET_32BIT) - return CC_CZmode; - - /* FALLTHROUGH */ - - case LT: - case LE: - case GT: - case GE: - /* DImode signed and unsigned comparisons can be implemented - by cmp + sbcs with a scratch register, but that does not - set the Z flag - we must reverse GT/LE/GTU/LEU. */ - gcc_assert (op != EQ && op != NE); - return CC_NCVmode; - - default: - gcc_unreachable (); - } - } - if (GET_MODE_CLASS (GET_MODE (x)) == MODE_CC) return GET_MODE (x); @@ -15673,81 +15623,8 @@ arm_gen_dicompare_reg (rtx_code code, rtx x, rtx y, rtx scratch) } default: - break; - } - - /* We might have X as a constant, Y as a register because of the predicates - used for cmpdi. If so, force X to a register here. */ - if (!REG_P (x)) - x = force_reg (DImode, x); - - mode = SELECT_CC_MODE (code, x, y); - cc_reg = gen_rtx_REG (mode, CC_REGNUM); - - if (mode != CC_CZmode) - { - rtx clobber, set; - - /* To compare two non-zero values for equality, XOR them and - then compare against zero. Not used for ARM mode; there - CC_CZmode is cheaper. */ - if (mode == CC_Zmode) - { - mode = CC_NOOVmode; - PUT_MODE (cc_reg, mode); - if (y != const0_rtx) - { - gcc_assert (CONST_INT_P (y)); - rtx xlo, xhi, ylo, yhi; - arm_decompose_di_binop (x, y, &xlo, &xhi, &ylo, &yhi); - if (!scratch) - scratch = gen_reg_rtx (SImode); - if (ylo == const0_rtx) - { - 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)); - y = xlo; - } - else - { - gcc_assert (yhi == const0_rtx); - 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)); - y = xhi; - } - x = gen_rtx_IOR (SImode, scratch, y); - y = const0_rtx; - } - else - 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) - gcc_assert (scratch != NULL && GET_MODE (scratch) == SImode); - else - scratch = gen_rtx_SCRATCH (SImode); - - clobber = gen_rtx_CLOBBER (VOIDmode, scratch); - set = gen_rtx_SET (cc_reg, gen_rtx_COMPARE (mode, x, y)); - emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, clobber))); - } - else - { - if (!cmpdi_operand (y, mode)) - y = force_reg (DImode, y); - - emit_set_insn (cc_reg, gen_rtx_COMPARE (mode, x, y)); + gcc_unreachable (); } - - return cc_reg; } /* X and Y are two things to compare using CODE. Emit the compare insn and @@ -24051,28 +23928,6 @@ maybe_get_arm_condition_code (rtx comparison) default: return ARM_NV; } - case E_CC_CZmode: - switch (comp_code) - { - case NE: return ARM_NE; - case EQ: return ARM_EQ; - case GEU: return ARM_CS; - case GTU: return ARM_HI; - case LEU: return ARM_LS; - case LTU: return ARM_CC; - default: return ARM_NV; - } - - case E_CC_NCVmode: - switch (comp_code) - { - case GE: return ARM_GE; - case LT: return ARM_LT; - case GEU: return ARM_CS; - case LTU: return ARM_CC; - default: return ARM_NV; - } - case E_CC_NVmode: switch (comp_code) { diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 8607c6f95da..eaadfd64128 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -6545,51 +6545,6 @@ (define_insn "*arm_cmpsi_negshiftsi_si" (set_attr "predicable" "yes")] ) -;; DImode comparisons. The generic code generates branches that -;; if-conversion cannot reduce to a conditional compare, so we do -;; that directly. - -(define_insn "*arm_cmpdi_insn" - [(set (reg:CC_NCV CC_REGNUM) - (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r") - (match_operand:DI 1 "arm_di_operand" "rDi"))) - (clobber (match_scratch:SI 2 "=r"))] - "TARGET_32BIT" - "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1" - [(set_attr "conds" "set") - (set_attr "length" "8") - (set_attr "type" "multiple")] -) - -(define_insn_and_split "*arm_cmpdi_unsigned" - [(set (reg:CC_CZ CC_REGNUM) - (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r") - (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))] - - "TARGET_32BIT" - "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1" - "&& reload_completed" - [(set (reg:CC CC_REGNUM) - (compare:CC (match_dup 2) (match_dup 3))) - (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0)) - (set (reg:CC CC_REGNUM) - (compare:CC (match_dup 0) (match_dup 1))))] - { - operands[2] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - if (CONST_INT_P (operands[1])) - operands[3] = gen_highpart_mode (SImode, DImode, operands[1]); - else - operands[3] = gen_highpart (SImode, operands[1]); - operands[1] = gen_lowpart (SImode, operands[1]); - } - [(set_attr "conds" "set") - (set_attr "enabled_for_short_it" "yes,yes,no,*") - (set_attr "arch" "t2,t2,t2,a") - (set_attr "length" "6,6,10,8") - (set_attr "type" "multiple")] -) - ; This insn allows redundant compares to be removed by cse, nothing should ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that ; is deleted later on. The match_dup will match the mode here, so that From patchwork Fri Oct 18 19:48:50 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: 1179647 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511335-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="JcXkLH7F"; dkim-atps=neutral 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 46vxhl2WcKz9sP7 for ; Sat, 19 Oct 2019 07:00:07 +1100 (AEDT) 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=yhmsjhuftypndt4l vokJUlHLTavbZSXyOYG4ZinC9Wa7SPmD6s6NE2r3rvaiZzPIVBWDhQ1UjsjkFKC5 bDtoUkfVuU7bBZ9PT7V3IK2BJlJZ2tC+/+939zYQOFgeJOR/z0gFpaAFpMbP4F3U qeRB5wGPGlGfUZPi/PAUJ3AFfhE= 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=9HtAt3H0whpp46X8SZQ6ht LNzuc=; b=JcXkLH7Fk1ua8AaRW6sZq8JUsXFRV0WWTrie/c9dFub66dyOvJEOZf FmMZYvewmjqY5KVX3mzBCz8IPrc06umglb2Bah6r90FUpGDkjXOdAmz1i3J02tHR D3MwyWysQI3X2Cl4WoLqaz3yNa9siQeQlWF5l2h6Ws3mhip0Snzyk= Received: (qmail 121868 invoked by alias); 18 Oct 2019 19:56:37 -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 115904 invoked by uid 89); 18 Oct 2019 19:55:51 -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, KAM_NUMSUBJECT, SPF_FAIL autolearn=ham version=3.3.1 spammy=rework 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:47 +0000 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iLYLd-0005AO-50 for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:42 -0400 Received: from [217.140.110.172] (port=42752 helo=foss.arm.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1iLYLc-00054V-Sn for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:41 -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 7D0661758; Fri, 18 Oct 2019 12:49:25 -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 0A8893F6C4; Fri, 18 Oct 2019 12:49:24 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 19/29] [arm] Handle immediate values in uaddvsi4 Date: Fri, 18 Oct 2019 20:48:50 +0100 Message-Id: <20191018194900.34795-20-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 The uaddv patterns in the arm back-end do not currenty handle immediates during expansion. This patch adds this support for uaddvsi4. It's really a stepping-stone towards early expansion of uaddvdi4, but it complete and a useful change in its own right. Whilst making this change I also observed that we really had two patterns that did exactly the same thing, but with slightly different properties; consequently I've cleaned up all of the add-and-compare patterns to bring some consistency. * config/arm/arm.md (adddi3): Call gen_addsi3_compare_op1. * (uaddv4): Delete expansion pattern. (uaddvsi4): New pattern. (uaddvdi4): Likewise. (addsi3_compareC): Delete pattern, change callers to use addsi3_compare_op1. (addsi3_compare_op1): No-longer anonymous. Clean up constraints to reduce the number of alternatives and re-work type attribute handling. (addsi3_compare_op2): Clean up constraints to reduce the number of alternatives and re-work type attribute handling. (compare_addsi2_op0): Likewise. (compare_addsi2_op1): Likewise. --- gcc/config/arm/arm.md | 118 ++++++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 56 deletions(-) diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index eaadfd64128..4ea6f4b226c 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -470,7 +470,7 @@ (define_expand "adddi3" if (!arm_not_operand (hi_op2, SImode)) hi_op2 = force_reg (SImode, hi_op2); - emit_insn (gen_addsi3_compareC (lo_dest, lo_op1, lo_op2)); + emit_insn (gen_addsi3_compare_op1 (lo_dest, lo_op1, lo_op2)); rtx carry = gen_rtx_LTU (SImode, gen_rtx_REG (CC_Cmode, CC_REGNUM), const0_rtx); if (hi_op2 == const0_rtx) @@ -501,14 +501,27 @@ (define_expand "addv4" DONE; }) -(define_expand "uaddv4" - [(match_operand:SIDI 0 "register_operand") - (match_operand:SIDI 1 "register_operand") - (match_operand:SIDI 2 "register_operand") +(define_expand "uaddvsi4" + [(match_operand:SI 0 "s_register_operand") + (match_operand:SI 1 "s_register_operand") + (match_operand:SI 2 "arm_add_operand") (match_operand 3 "")] "TARGET_32BIT" { - emit_insn (gen_add3_compareC (operands[0], operands[1], operands[2])); + emit_insn (gen_addsi3_compare_op1 (operands[0], operands[1], operands[2])); + arm_gen_unlikely_cbranch (LTU, CC_Cmode, operands[3]); + + DONE; +}) + +(define_expand "uaddvdi4" + [(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_adddi3_compareC (operands[0], operands[1], operands[2])); arm_gen_unlikely_cbranch (LTU, CC_Cmode, operands[3]); DONE; @@ -639,19 +652,6 @@ (define_insn "adddi3_compareC" (set_attr "type" "multiple")] ) -(define_insn "addsi3_compareC" - [(set (reg:CC_C CC_REGNUM) - (compare:CC_C (plus:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "register_operand" "r")) - (match_dup 1))) - (set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_32BIT" - "adds%?\\t%0, %1, %2" - [(set_attr "conds" "set") - (set_attr "type" "alus_sreg")] -) - (define_insn "addsi3_compare0" [(set (reg:CC_NOOV CC_REGNUM) (compare:CC_NOOV @@ -770,13 +770,13 @@ (define_peephole2 ;; the operands, and we know that the use of the condition code is ;; either GEU or LTU, so we can use the carry flag from the addition ;; instead of doing the compare a second time. -(define_insn "*addsi3_compare_op1" +(define_insn "addsi3_compare_op1" [(set (reg:CC_C CC_REGNUM) (compare:CC_C - (plus:SI (match_operand:SI 1 "s_register_operand" "l,0,l,0,r,r,r") - (match_operand:SI 2 "arm_add_operand" "lPd,Py,lPx,Pw,I,L,r")) + (plus:SI (match_operand:SI 1 "s_register_operand" "l,0,l,0,rk,rk") + (match_operand:SI 2 "arm_add_operand" "lPd,Py,lPx,Pw,rkI,L")) (match_dup 1))) - (set (match_operand:SI 0 "s_register_operand" "=l,l,l,l,r,r,r") + (set (match_operand:SI 0 "s_register_operand" "=l,l,l,l,rk,rk") (plus:SI (match_dup 1) (match_dup 2)))] "TARGET_32BIT" "@ @@ -785,22 +785,23 @@ (define_insn "*addsi3_compare_op1" subs%?\\t%0, %1, #%n2 subs%?\\t%0, %0, #%n2 adds%?\\t%0, %1, %2 - subs%?\\t%0, %1, #%n2 - adds%?\\t%0, %1, %2" + subs%?\\t%0, %1, #%n2" [(set_attr "conds" "set") - (set_attr "arch" "t2,t2,t2,t2,*,*,*") - (set_attr "length" "2,2,2,2,4,4,4") - (set_attr "type" - "alus_sreg,alus_imm,alus_sreg,alus_imm,alus_imm,alus_imm,alus_sreg")] + (set_attr "arch" "t2,t2,t2,t2,*,*") + (set_attr "length" "2,2,2,2,4,4") + (set (attr "type") + (if_then_else (match_operand 2 "const_int_operand") + (const_string "alu_imm") + (const_string "alu_sreg")))] ) (define_insn "*addsi3_compare_op2" [(set (reg:CC_C CC_REGNUM) (compare:CC_C - (plus:SI (match_operand:SI 1 "s_register_operand" "l,0,l,0,r,r,r") - (match_operand:SI 2 "arm_add_operand" "lPd,Py,lPx,Pw,I,L,r")) + (plus:SI (match_operand:SI 1 "s_register_operand" "l,0,l,0,r,r") + (match_operand:SI 2 "arm_add_operand" "lPd,Py,lPx,Pw,rI,L")) (match_dup 2))) - (set (match_operand:SI 0 "s_register_operand" "=l,l,l,l,r,r,r") + (set (match_operand:SI 0 "s_register_operand" "=l,l,l,l,r,r") (plus:SI (match_dup 1) (match_dup 2)))] "TARGET_32BIT" "@ @@ -809,55 +810,60 @@ (define_insn "*addsi3_compare_op2" subs%?\\t%0, %1, #%n2 subs%?\\t%0, %0, #%n2 adds%?\\t%0, %1, %2 - subs%?\\t%0, %1, #%n2 - adds%?\\t%0, %1, %2" + subs%?\\t%0, %1, #%n2" [(set_attr "conds" "set") - (set_attr "arch" "t2,t2,t2,t2,*,*,*") - (set_attr "length" "2,2,2,2,4,4,4") - (set_attr "type" - "alus_sreg,alus_imm,alus_sreg,alus_imm,alus_imm,alus_imm,alus_sreg")] + (set_attr "arch" "t2,t2,t2,t2,*,*") + (set_attr "length" "2,2,2,2,4,4") + (set (attr "type") + (if_then_else (match_operand 2 "const_int_operand") + (const_string "alu_imm") + (const_string "alu_sreg")))] ) (define_insn "*compare_addsi2_op0" [(set (reg:CC_C CC_REGNUM) (compare:CC_C - (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r") - (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r")) + (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r") + (match_operand:SI 1 "arm_add_operand" "l,Pw,rI,L")) (match_dup 0)))] "TARGET_32BIT" "@ - cmp%?\\t%0, #%n1 - cmn%?\\t%0, %1 cmn%?\\t%0, %1 cmp%?\\t%0, #%n1 - cmn%?\\t%0, %1" + cmn%?\\t%0, %1 + cmp%?\\t%0, #%n1" [(set_attr "conds" "set") (set_attr "predicable" "yes") - (set_attr "arch" "t2,t2,*,*,*") - (set_attr "predicable_short_it" "yes,yes,no,no,no") - (set_attr "length" "2,2,4,4,4") - (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")] + (set_attr "arch" "t2,t2,*,*") + (set_attr "predicable_short_it" "yes,yes,no,no") + (set_attr "length" "2,2,4,4") + (set (attr "type") + (if_then_else (match_operand 1 "const_int_operand") + (const_string "alu_imm") + (const_string "alu_sreg")))] ) (define_insn "*compare_addsi2_op1" [(set (reg:CC_C CC_REGNUM) (compare:CC_C - (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r") - (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r")) + (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r") + (match_operand:SI 1 "arm_add_operand" "l,Pw,rI,L")) (match_dup 1)))] "TARGET_32BIT" "@ - cmp%?\\t%0, #%n1 - cmn%?\\t%0, %1 cmn%?\\t%0, %1 cmp%?\\t%0, #%n1 - cmn%?\\t%0, %1" + cmn%?\\t%0, %1 + cmp%?\\t%0, #%n1" [(set_attr "conds" "set") (set_attr "predicable" "yes") - (set_attr "arch" "t2,t2,*,*,*") - (set_attr "predicable_short_it" "yes,yes,no,no,no") - (set_attr "length" "2,2,4,4,4") - (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")] + (set_attr "arch" "t2,t2,*,*") + (set_attr "predicable_short_it" "yes,yes,no,no") + (set_attr "length" "2,2,4,4") + (set (attr "type") + (if_then_else (match_operand 1 "const_int_operand") + (const_string "alu_imm") + (const_string "alu_sreg")))] ) (define_insn "addsi3_carryin" From patchwork Fri Oct 18 19:48:51 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: 1179642 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511330-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="WBPJLhPY"; dkim-atps=neutral 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 46vxgW5SyWz9sP7 for ; Sat, 19 Oct 2019 06:59:03 +1100 (AEDT) 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=IK2OiCWOkyUC7BgF Gz8A7Jn3/3T59V0oDSe78JId/vljMg9JZJQCTRqCqQsEy0CP0OjdR/QlOxMzBoeA LRaabVxeILD4e7nBfBk73Kv3HFr7p+DWFKHQWlJGZawLYCgEgkgk69L4Rx0r3nyP YmnCHYPFv6yk8ZswvTyCblNLp/4= 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=pUy9ZSwki18MhLmyj/0IRR Hprro=; b=WBPJLhPYLs0OYiDbiIQSiSQUaSdU/dzCxJjX4qt6YGg/+IxwMiF+76 U5Fu3YJ8zm96oiVWth6zA/EIKKJgvppEhkNouWm/leri/xEzKzUxzdq56kSSJm34 HOOy3eRPpAZ8OD0HaYe7IPheOlevSUshUqbS2eBx+lCxUx8sTPq1E= Received: (qmail 115587 invoked by alias); 18 Oct 2019 19:55:49 -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 114987 invoked by uid 89); 18 Oct 2019 19:55:45 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-19.1 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= 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:43 +0000 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iLYLd-0005AT-5P for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:42 -0400 Received: from [217.140.110.172] (port=42766 helo=foss.arm.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1iLYLc-00055W-TB for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:41 -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 30E51175A; Fri, 18 Oct 2019 12:49:26 -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 B262B3F6C4; Fri, 18 Oct 2019 12:49:25 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 20/29] [arm] Early expansion of uaddvdi4. Date: Fri, 18 Oct 2019 20:48:51 +0100 Message-Id: <20191018194900.34795-21-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 code borrows strongly on the uaddvti4 expansion for aarch64 since the principles are similar. Firstly, if the one of the low words of the expansion is 0, we can simply copy the other low word to the destination and use uaddvsi4 for the upper word. If that doesn't work we have to handle three possible cases for the upper work (the lower word is simply an add-with-carry operation as for adddi3): zero in the upper word, some other constant and a register (each has a different canonicalization). We use CC_ADCmode (a new CC mode variant) to describe the cases as the introduction of the carry means we can no-longer use the normal overflow trick of comparing the sum against one of the operands. * config/arm/arm-modes.def (CC_ADC): New CC mode. * config/arm/arm.c (arm_select_cc_mode): Detect selection of CC_ADCmode. (maybe_get_arm_condition_code): Handle CC_ADCmode. * config/arm/arm.md (uaddvdi4): Early expansion of unsigned addition with overflow. (addsi3_cin_cout_reg, addsi3_cin_cout_imm, addsi3_cin_cout_0): New expand patterns. (addsi3_cin_cout_reg_insn, addsi3_cin_cout_0_insn): New insn patterns (addsi3_cin_cout_imm_insn): Likewise. (adddi3_compareC): Delete insn. * config/arm/predicates.md (arm_carry_operation): Handle CC_ADCmode. --- gcc/config/arm/arm-modes.def | 4 + gcc/config/arm/arm.c | 16 ++++ gcc/config/arm/arm.md | 171 +++++++++++++++++++++++++++++++---- gcc/config/arm/predicates.md | 2 +- 4 files changed, 173 insertions(+), 20 deletions(-) diff --git a/gcc/config/arm/arm-modes.def b/gcc/config/arm/arm-modes.def index f0eb8415b93..a6b520df32d 100644 --- a/gcc/config/arm/arm-modes.def +++ b/gcc/config/arm/arm-modes.def @@ -42,6 +42,9 @@ ADJUST_FLOAT_FORMAT (HF, ((arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE) CC_Bmode should be used if only the C flag is correct after a subtract (eg after an unsigned borrow with carry-in propagation). (used for DImode signed comparisons). + CC_ADCmode is used when the carry is formed from the output of ADC for an + addtion. In this case we cannot use the trick of comparing the sum + against one of the other operands. CCmode should be used otherwise. */ CC_MODE (CC_NOOV); @@ -65,6 +68,7 @@ CC_MODE (CC_C); CC_MODE (CC_B); CC_MODE (CC_N); CC_MODE (CC_V); +CC_MODE (CC_ADC); /* Vector modes. */ VECTOR_MODES (INT, 4); /* V4QI V2HI */ diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 6da2a368d9f..eebbdc3d9c2 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -15387,6 +15387,14 @@ arm_select_cc_mode (enum rtx_code op, rtx x, rtx y) && (rtx_equal_p (XEXP (x, 0), y) || rtx_equal_p (XEXP (x, 1), y))) return CC_Cmode; + if (GET_MODE (x) == DImode + && GET_CODE (x) == PLUS + && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND + && CONST_INT_P (y) + && UINTVAL (y) == 0x800000000 + && (op == GEU || op == LTU)) + return CC_ADCmode; + if (GET_MODE (x) == DImode && (op == GE || op == LT) && GET_CODE (x) == SIGN_EXTEND @@ -23952,6 +23960,14 @@ maybe_get_arm_condition_code (rtx comparison) default: return ARM_NV; } + case E_CC_ADCmode: + switch (comp_code) + { + case GEU: return ARM_CS; + case LTU: return ARM_CC; + default: return ARM_NV; + } + case E_CCmode: case E_CC_RSBmode: switch (comp_code) diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 4ea6f4b226c..9f0e43571fd 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -517,16 +517,165 @@ (define_expand "uaddvsi4" (define_expand "uaddvdi4" [(match_operand:DI 0 "s_register_operand") (match_operand:DI 1 "s_register_operand") - (match_operand:DI 2 "s_register_operand") + (match_operand:DI 2 "reg_or_int_operand") (match_operand 3 "")] "TARGET_32BIT" { - emit_insn (gen_adddi3_compareC (operands[0], operands[1], operands[2])); - arm_gen_unlikely_cbranch (LTU, CC_Cmode, operands[3]); + rtx lo_result, hi_result; + rtx lo_op1, hi_op1, lo_op2, hi_op2; + arm_decompose_di_binop (operands[1], operands[2], &lo_op1, &hi_op1, + &lo_op2, &hi_op2); + lo_result = gen_lowpart (SImode, operands[0]); + hi_result = gen_highpart (SImode, operands[0]); + + if (lo_op2 == const0_rtx) + { + emit_move_insn (lo_result, lo_op1); + if (!arm_add_operand (hi_op2, SImode)) + hi_op2 = force_reg (SImode, hi_op2); + + gen_uaddvsi4 (hi_result, hi_op1, hi_op2, operands[3]); + } + else + { + if (!arm_add_operand (lo_op2, SImode)) + lo_op2 = force_reg (SImode, lo_op2); + if (!arm_not_operand (hi_op2, SImode)) + hi_op2 = force_reg (SImode, hi_op2); + + emit_insn (gen_addsi3_compare_op1 (lo_result, lo_op1, lo_op2)); + + if (hi_op2 == const0_rtx) + emit_insn (gen_addsi3_cin_cout_0 (hi_result, hi_op1)); + else if (CONST_INT_P (hi_op2)) + emit_insn (gen_addsi3_cin_cout_imm (hi_result, hi_op1, hi_op2)); + else + emit_insn (gen_addsi3_cin_cout_reg (hi_result, hi_op1, hi_op2)); + + arm_gen_unlikely_cbranch (GEU, CC_ADCmode, operands[3]); + } DONE; }) +(define_expand "addsi3_cin_cout_reg" + [(parallel + [(set (match_dup 3) + (compare:CC_ADC + (plus:DI + (plus:DI (match_dup 4) + (zero_extend:DI (match_operand:SI 1 "s_register_operand"))) + (zero_extend:DI (match_operand:SI 2 "s_register_operand"))) + (const_int 4294967296))) + (set (match_operand:SI 0 "s_register_operand") + (plus:SI (plus:SI (match_dup 5) (match_dup 1)) + (match_dup 2)))])] + "TARGET_32BIT" + { + operands[3] = gen_rtx_REG (CC_ADCmode, CC_REGNUM); + rtx ccin = gen_rtx_REG (CC_Cmode, CC_REGNUM); + operands[4] = gen_rtx_LTU (DImode, ccin, const0_rtx); + operands[5] = gen_rtx_LTU (SImode, ccin, const0_rtx); + } +) + +(define_insn "*addsi3_cin_cout_reg_insn" + [(set (reg:CC_ADC CC_REGNUM) + (compare:CC_ADC + (plus:DI + (plus:DI + (match_operand:DI 3 "arm_carry_operation" "") + (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))) + (zero_extend:DI (match_operand:SI 2 "s_register_operand" "l,r"))) + (const_int 4294967296))) + (set (match_operand:SI 0 "s_register_operand" "=l,r") + (plus:SI (plus:SI (match_operand:SI 4 "arm_carry_operation" "") + (match_dup 1)) + (match_dup 2)))] + "TARGET_32BIT" + "@ + adcs%?\\t%0, %0, %2 + adcs%?\\t%0, %1, %2" + [(set_attr "type" "alus_sreg") + (set_attr "arch" "t2,*") + (set_attr "length" "2,4")] +) + +(define_expand "addsi3_cin_cout_imm" + [(parallel + [(set (match_dup 3) + (compare:CC_ADC + (plus:DI + (plus:DI (match_dup 4) + (zero_extend:DI (match_operand:SI 1 "s_register_operand"))) + (match_dup 6)) + (const_int 4294967296))) + (set (match_operand:SI 0 "s_register_operand") + (plus:SI (plus:SI (match_dup 5) (match_dup 1)) + (match_operand:SI 2 "arm_adcimm_operand")))])] + "TARGET_32BIT" + { + operands[3] = gen_rtx_REG (CC_ADCmode, CC_REGNUM); + rtx ccin = gen_rtx_REG (CC_Cmode, CC_REGNUM); + operands[4] = gen_rtx_LTU (DImode, ccin, const0_rtx); + operands[5] = gen_rtx_LTU (SImode, ccin, const0_rtx); + operands[6] = GEN_INT (UINTVAL (operands[2]) & 0xffffffff); + } +) + +(define_insn "*addsi3_cin_cout_imm_insn" + [(set (reg:CC_ADC CC_REGNUM) + (compare:CC_ADC + (plus:DI + (plus:DI + (match_operand:DI 3 "arm_carry_operation" "") + (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r,r"))) + (match_operand:DI 5 "const_int_operand" "n,n")) + (const_int 4294967296))) + (set (match_operand:SI 0 "s_register_operand" "=r,r") + (plus:SI (plus:SI (match_operand:SI 4 "arm_carry_operation" "") + (match_dup 1)) + (match_operand:SI 2 "arm_adcimm_operand" "I,K")))] + "TARGET_32BIT + && (UINTVAL (operands[2]) & 0xffffffff) == UINTVAL (operands[5])" + "@ + adcs%?\\t%0, %1, %2 + sbcs%?\\t%0, %1, #%B2" + [(set_attr "type" "alus_imm")] +) + +(define_expand "addsi3_cin_cout_0" + [(parallel + [(set (match_dup 2) + (compare:CC_ADC + (plus:DI (match_dup 3) + (zero_extend:DI (match_operand:SI 1 "s_register_operand"))) + (const_int 4294967296))) + (set (match_operand:SI 0 "s_register_operand") + (plus:SI (match_dup 4) (match_dup 1)))])] + "TARGET_32BIT" + { + operands[2] = gen_rtx_REG (CC_ADCmode, CC_REGNUM); + rtx ccin = gen_rtx_REG (CC_Cmode, CC_REGNUM); + operands[3] = gen_rtx_LTU (DImode, ccin, const0_rtx); + operands[4] = gen_rtx_LTU (SImode, ccin, const0_rtx); + } +) + +(define_insn "*addsi3_cin_cout_0_insn" + [(set (reg:CC_ADC CC_REGNUM) + (compare:CC_ADC + (plus:DI + (match_operand:DI 2 "arm_carry_operation" "") + (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))) + (const_int 4294967296))) + (set (match_operand:SI 0 "s_register_operand" "=r") + (plus:SI (match_operand:SI 3 "arm_carry_operation" "") (match_dup 1)))] + "TARGET_32BIT" + "adcs%?\\t%0, %1, #0" + [(set_attr "type" "alus_imm")] +) + (define_expand "addsi3" [(set (match_operand:SI 0 "s_register_operand") (plus:SI (match_operand:SI 1 "s_register_operand") @@ -636,22 +785,6 @@ (define_insn "addsi3_compareV" (set_attr "type" "alus_sreg")] ) -(define_insn "adddi3_compareC" - [(set (reg:CC_C CC_REGNUM) - (compare:CC_C - (plus:DI - (match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "register_operand" "r")) - (match_dup 1))) - (set (match_operand:DI 0 "register_operand" "=&r") - (plus:DI (match_dup 1) (match_dup 2)))] - "TARGET_32BIT" - "adds\\t%Q0, %Q1, %Q2;adcs\\t%R0, %R1, %R2" - [(set_attr "conds" "set") - (set_attr "length" "8") - (set_attr "type" "multiple")] -) - (define_insn "addsi3_compare0" [(set (reg:CC_NOOV CC_REGNUM) (compare:CC_NOOV diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md index d9470df8093..8a8f10ccb50 100644 --- a/gcc/config/arm/predicates.md +++ b/gcc/config/arm/predicates.md @@ -376,7 +376,7 @@ (define_special_predicate "arm_carry_operation" machine_mode ccmode = GET_MODE (op0); if (ccmode == CC_Cmode) return GET_CODE (op) == LTU; - else if (ccmode == CCmode || ccmode == CC_RSBmode) + else if (ccmode == CCmode || ccmode == CC_RSBmode || ccmode == CC_ADCmode) return GET_CODE (op) == GEU; return false; From patchwork Fri Oct 18 19:48:52 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: 1179644 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511332-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="F74nLxX2"; dkim-atps=neutral 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 46vxh01M46z9sPJ for ; Sat, 19 Oct 2019 06:59:27 +1100 (AEDT) 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=sJU0H0TBH/Q9lx6L 00ufjA7mysJgs3s0y142dkgg6+IXvaqjnFqR6Wy3LsVdiv1DFE8XoTrUCr+qtG0P EQDnsSUZlcgz+Wnv1TsHpqmqDMcSiyJspkyuhsMoyTff3QEgJ39vYQS/9P9oLu9o 9XoO3B97Lq1gFe3hqUXcKreCMTM= 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=pjZcwv0YFOQeGQWIK36Hni hjyAY=; b=F74nLxX2e1Mt1zRJhh+KPvqDnGUvLYlc4p+WeLB6xzVD8lVxPeLEnY dnoU0LsJHMWmdlSqJvVrrzGtWcJRGRDKZdKfaTbl8mnE0Ovr8ZvzTG7ohfJhYW5u 6nOmobYLV3a1kPmOB7r4d7LfPc9Z6dJIvJS3JaxXyCZEIYQrL+WpY= Received: (qmail 117569 invoked by alias); 18 Oct 2019 19:56:04 -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 115224 invoked by uid 89); 18 Oct 2019 19:55:47 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-19.1 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= 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:45 +0000 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iLYLd-0005BF-Or for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:42 -0400 Received: from [217.140.110.172] (port=42774 helo=foss.arm.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1iLYLd-000563-Ft for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:41 -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 D8D26175D; Fri, 18 Oct 2019 12:49:26 -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 661B23F6C4; Fri, 18 Oct 2019 12:49:26 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 21/29] [arm] Improve code generation for addvsi4. Date: Fri, 18 Oct 2019 20:48:52 +0100 Message-Id: <20191018194900.34795-22-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 Similar to the improvements for uaddvsi4, this patch improves the code generation for addvsi4 to handle immediates and to add alternatives that better target thumb2. To do this we separate out the expansion of uaddvsi4 from that of uaddvdi4 and then add an additional pattern to handle constants. Also, while doing this I've fixed the incorrect usage of NE instead of COMPARE in the generated RTL. * config/arm/arm.md (addv4): Delete. (addvsi4): New pattern. Handle immediate values that the architecture supports. (addvdi4): New pattern. (addsi3_compareV): Rename to ... (addsi3_compareV_reg): ... this. Add constraints for thumb2 variants and use COMPARE rather than NE. (addsi3_compareV_imm): New pattern. * config/arm/arm.c (arm_select_cc_mode): Return CC_Vmode for a signed-overflow check. --- gcc/config/arm/arm.c | 8 ++++++ gcc/config/arm/arm.md | 63 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index eebbdc3d9c2..638c82df25f 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -15411,6 +15411,14 @@ arm_select_cc_mode (enum rtx_code op, rtx x, rtx y) || arm_borrow_operation (y, DImode))) return CC_Bmode; + if (GET_MODE (x) == DImode + && (op == EQ || op == NE) + && GET_CODE (x) == PLUS + && GET_CODE (XEXP (x, 0)) == SIGN_EXTEND + && GET_CODE (y) == SIGN_EXTEND + && GET_CODE (XEXP (y, 0)) == PLUS) + return CC_Vmode; + if (GET_MODE_CLASS (GET_MODE (x)) == MODE_CC) return GET_MODE (x); diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 9f0e43571fd..b5214c79c35 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -488,14 +488,30 @@ (define_expand "adddi3" " ) -(define_expand "addv4" - [(match_operand:SIDI 0 "register_operand") - (match_operand:SIDI 1 "register_operand") - (match_operand:SIDI 2 "register_operand") +(define_expand "addvsi4" + [(match_operand:SI 0 "s_register_operand") + (match_operand:SI 1 "s_register_operand") + (match_operand:SI 2 "arm_add_operand") (match_operand 3 "")] "TARGET_32BIT" { - emit_insn (gen_add3_compareV (operands[0], operands[1], operands[2])); + if (CONST_INT_P (operands[2])) + emit_insn (gen_addsi3_compareV_imm (operands[0], operands[1], operands[2])); + else + emit_insn (gen_addsi3_compareV_reg (operands[0], operands[1], operands[2])); + arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); + + DONE; +}) + +(define_expand "addvdi4" + [(match_operand:DI 0 "register_operand") + (match_operand:DI 1 "register_operand") + (match_operand:DI 2 "register_operand") + (match_operand 3 "")] + "TARGET_32BIT" +{ + emit_insn (gen_adddi3_compareV (operands[0], operands[1], operands[2])); arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); DONE; @@ -770,21 +786,48 @@ (define_insn "adddi3_compareV" (set_attr "type" "multiple")] ) -(define_insn "addsi3_compareV" +(define_insn "addsi3_compareV_reg" [(set (reg:CC_V CC_REGNUM) - (ne:CC_V + (compare:CC_V (plus:DI - (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) - (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))) + (sign_extend:DI (match_operand:SI 1 "register_operand" "%l,0,r")) + (sign_extend:DI (match_operand:SI 2 "register_operand" "l,r,r"))) (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2))))) - (set (match_operand:SI 0 "register_operand" "=r") + (set (match_operand:SI 0 "register_operand" "=l,r,r") (plus:SI (match_dup 1) (match_dup 2)))] "TARGET_32BIT" "adds%?\\t%0, %1, %2" [(set_attr "conds" "set") + (set_attr "arch" "t2,t2,*") + (set_attr "length" "2,2,4") (set_attr "type" "alus_sreg")] ) +(define_insn "addsi3_compareV_imm" + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (plus:DI + (sign_extend:DI + (match_operand:SI 1 "register_operand" "l,0,l,0,r,r")) + (match_operand 2 "arm_addimm_operand" "Pd,Py,Px,Pw,I,L")) + (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2))))) + (set (match_operand:SI 0 "register_operand" "=l,l,l,l,r,r") + (plus:SI (match_dup 1) (match_dup 2)))] + "TARGET_32BIT + && INTVAL (operands[2]) == ARM_SIGN_EXTEND (INTVAL (operands[2]))" + "@ + adds%?\\t%0, %1, %2 + adds%?\\t%0, %0, %2 + subs%?\\t%0, %1, #%n2 + subs%?\\t%0, %0, #%n2 + adds%?\\t%0, %1, %2 + subs%?\\t%0, %1, #%n2" + [(set_attr "conds" "set") + (set_attr "arch" "t2,t2,t2,t2,*,*") + (set_attr "length" "2,2,2,2,4,4") + (set_attr "type" "alus_imm")] +) + (define_insn "addsi3_compare0" [(set (reg:CC_NOOV CC_REGNUM) (compare:CC_NOOV From patchwork Fri Oct 18 19:48:53 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: 1179643 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511331-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="CoZ9NN/K"; dkim-atps=neutral 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 46vxgm0Tpgz9sP7 for ; Sat, 19 Oct 2019 06:59:15 +1100 (AEDT) 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=abWj8vcJu7A7uM7w OXi5zPoKc9z05nKJS9kSPwyyw7Lroc5UkQk34R+9Sgxm4ksGLt/AmEsq/e3tLRA3 1YL1cFxffoVbOp6HJH2Zdq+UDB+u1C04EAmdySuZwr+VnFwj7UJfX4tgYYoxpZXi ZUV+O/AHY32rS4ibK/tW7RcTmgM= 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=/Hn6m9pl2fXfQXDMrmUcZ+ XCxuk=; b=CoZ9NN/K33l86qKLuRzhfvAZvBo2olHM0bHFJxcaGhMWei+kQCnzdU YeTHF+kZjS966q1bHUsfCY/4O9KTdrPRhkRszsMIJmOlT8hn/xbJubjxNR+Y8bEv qZrJeIIjVehsVAAwGJw9RAFejzY/X48+cIf/WmsSxTJubAklnRojw= Received: (qmail 115730 invoked by alias); 18 Oct 2019 19:55:50 -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 114946 invoked by uid 89); 18 Oct 2019 19:55:44 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-19.1 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= 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:43 +0000 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iLYLd-0005BT-Q5 for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:42 -0400 Received: from [217.140.110.172] (port=42782 helo=foss.arm.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1iLYLd-00056C-HP for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:41 -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 8CA231762; Fri, 18 Oct 2019 12:49:27 -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 19F613F6C4; Fri, 18 Oct 2019 12:49:26 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 22/29] [arm] Allow the summation result of signed add-with-overflow to be discarded. Date: Fri, 18 Oct 2019 20:48:53 +0100 Message-Id: <20191018194900.34795-23-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 matches the signed add-with-overflow patterns when the summation itself is dropped. In this case we can use CMN (or CMP with some immediates). There are a small number of constants in thumb2 where this can result in less dense code (as we lack 16-bit CMN with immediate patterns). To handle this we use peepholes to try these alternatives when either a scratch is available (0 <= i <= 7) or the original register is dead (0 <= i <= 255). We don't use a scratch in the pattern as if those conditions are not satisfied then the 32-bit form is preferable to forcing a reload. * config/arm/arm.md (addsi3_compareV_reg_nosum): New insn. (addsi3_compareV_imm_nosum): New insn. Also add peephole2 patterns to transform this back into the summation version when that leads to smaller code. --- gcc/config/arm/arm.md | 78 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index b5214c79c35..be002f77382 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -803,6 +803,21 @@ (define_insn "addsi3_compareV_reg" (set_attr "type" "alus_sreg")] ) +(define_insn "*addsi3_compareV_reg_nosum" + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (plus:DI + (sign_extend:DI (match_operand:SI 0 "register_operand" "%l,r")) + (sign_extend:DI (match_operand:SI 1 "register_operand" "l,r"))) + (sign_extend:DI (plus:SI (match_dup 0) (match_dup 1)))))] + "TARGET_32BIT" + "cmn%?\\t%0, %1" + [(set_attr "conds" "set") + (set_attr "arch" "t2,*") + (set_attr "length" "2,4") + (set_attr "type" "alus_sreg")] +) + (define_insn "addsi3_compareV_imm" [(set (reg:CC_V CC_REGNUM) (compare:CC_V @@ -828,6 +843,69 @@ (define_insn "addsi3_compareV_imm" (set_attr "type" "alus_imm")] ) +(define_insn "addsi3_compareV_imm_nosum" + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (plus:DI + (sign_extend:DI + (match_operand:SI 0 "register_operand" "l,r,r")) + (match_operand 1 "arm_addimm_operand" "Pw,I,L")) + (sign_extend:DI (plus:SI (match_dup 0) (match_dup 1)))))] + "TARGET_32BIT + && INTVAL (operands[1]) == ARM_SIGN_EXTEND (INTVAL (operands[1]))" + "@ + cmp%?\\t%0, #%n1 + cmn%?\\t%0, %1 + cmp%?\\t%0, #%n1" + [(set_attr "conds" "set") + (set_attr "arch" "t2,*,*") + (set_attr "length" "2,4,4") + (set_attr "type" "alus_imm")] +) + +;; We can handle more constants efficently if we can clobber either a scratch +;; or the other source operand. We deliberately leave this late as in +;; high register pressure situations it's not worth forcing any reloads. +(define_peephole2 + [(match_scratch:SI 2 "l") + (set (reg:CC_V CC_REGNUM) + (compare:CC_V + (plus:DI + (sign_extend:DI + (match_operand:SI 0 "low_register_operand")) + (match_operand 1 "const_int_operand")) + (sign_extend:DI (plus:SI (match_dup 0) (match_dup 1)))))] + "TARGET_THUMB2 + && satisfies_constraint_Pd (operands[1])" + [(parallel[ + (set (reg:CC_V CC_REGNUM) + (compare:CC_V + (plus:DI (sign_extend:DI (match_dup 0)) + (sign_extend:DI (match_dup 1))) + (sign_extend:DI (plus:SI (match_dup 0) (match_dup 1))))) + (set (match_dup 2) (plus:SI (match_dup 0) (match_dup 1)))])] +) + +(define_peephole2 + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (plus:DI + (sign_extend:DI + (match_operand:SI 0 "low_register_operand")) + (match_operand 1 "const_int_operand")) + (sign_extend:DI (plus:SI (match_dup 0) (match_dup 1)))))] + "TARGET_THUMB2 + && dead_or_set_p (peep2_next_insn (0), operands[0]) + && satisfies_constraint_Py (operands[1])" + [(parallel[ + (set (reg:CC_V CC_REGNUM) + (compare:CC_V + (plus:DI (sign_extend:DI (match_dup 0)) + (sign_extend:DI (match_dup 1))) + (sign_extend:DI (plus:SI (match_dup 0) (match_dup 1))))) + (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))])] +) + (define_insn "addsi3_compare0" [(set (reg:CC_NOOV CC_REGNUM) (compare:CC_NOOV From patchwork Fri Oct 18 19:48:54 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: 1179631 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511319-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="ZOYgAwLv"; dkim-atps=neutral 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 46vxcm1zxmz9sP7 for ; Sat, 19 Oct 2019 06:56:40 +1100 (AEDT) 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=j7pf2so/7XmKsbIA lNH4m+7hmGN6MuDQ7rV7o428RMEkCmB387lkdNQtjYI953yKFTn50Ew/zbDwo4uO rckL2ZRf4ea/XX28ifcK0AxE8jPZr+qmCwAK7UFZpH3+z5/McP7j6FksfoTzv1aT i65p5Bxk/dBbXdgXcVDB0ojfvIo= 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=ZzEHw71hKg2vr1Zhnj9oxq Yanug=; b=ZOYgAwLvHYgaJMsxWbK8TwwVQmza3HSOtrkCh5Ezx7JhrRoR8vIk5M 4J0TKnnCBYboTHKt2I0oblNUXMTmZGskGoRyz2npxqEx2M/R/1hHCNMNLEOhGGOn KZjF5VUKJlytOeruHNEnXRjKG+lBz3wuvwJE/oCg82xTr98syt0Rs= Received: (qmail 112767 invoked by alias); 18 Oct 2019 19:55:40 -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 110479 invoked by uid 89); 18 Oct 2019 19:55:32 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_NUMSUBJECT, SPF_PASS autolearn=ham version=3.3.1 spammy=1, 41 X-HELO: foss.arm.com Received: from Unknown (HELO foss.arm.com) (217.140.110.172) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 18 Oct 2019 19:55:30 +0000 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 40C401763; Fri, 18 Oct 2019 12:49:28 -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 C22C43F6C4; Fri, 18 Oct 2019 12:49:27 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 23/29] [arm] Early split addvdi4 Date: Fri, 18 Oct 2019 20:48:54 +0100 Message-Id: <20191018194900.34795-24-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 This patch adds early splitting for addvdi4; it's very similar to the uaddvdi4 splitter, but the details are just different enough in places, especially for the patterns that match the splitting, where we have to compare against the non-widened version to detect if overflow occurred. I've also added a testcase to the testsuite for a couple of constants that caught me out during the development of this patch. They're probably arm-specific values, but the test is generic enough that I've included it for all targets. [gcc] * config/arm/arm.c (arm_select_cc_mode): Allow either the first or second operand of the PLUS inside a DImode equality test to be sign-extend when selecting CC_Vmode. * config/arm/arm.md (addvdi4): Early-split the operation into SImode instructions. (addsi3_cin_vout_reg, addsi3_cin_vout_imm, addsi3_cin_vout_0): New expand patterns. (addsi3_cin_vout_reg_insn, addsi3_cin_vout_imm_insn): New patterns. (addsi3_cin_vout_0): Likewise. (adddi3_compareV): Delete. [gcc/testsuite] * gcc.dg/builtin-arith-overflow-3.c: New test. --- gcc/config/arm/arm.c | 3 +- gcc/config/arm/arm.md | 181 ++++++++++++++++-- .../gcc.dg/builtin-arith-overflow-3.c | 41 ++++ 3 files changed, 203 insertions(+), 22 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/builtin-arith-overflow-3.c diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 638c82df25f..c9abbb0f91d 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -15414,7 +15414,8 @@ 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 (XEXP (x, 0)) == SIGN_EXTEND + && (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) return CC_Vmode; diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index be002f77382..e9e0ca925d2 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -505,18 +505,173 @@ (define_expand "addvsi4" }) (define_expand "addvdi4" - [(match_operand:DI 0 "register_operand") - (match_operand:DI 1 "register_operand") - (match_operand:DI 2 "register_operand") + [(match_operand:DI 0 "s_register_operand") + (match_operand:DI 1 "s_register_operand") + (match_operand:DI 2 "reg_or_int_operand") (match_operand 3 "")] "TARGET_32BIT" { - emit_insn (gen_adddi3_compareV (operands[0], operands[1], operands[2])); - arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); + rtx lo_result, hi_result; + rtx lo_op1, hi_op1, lo_op2, hi_op2; + arm_decompose_di_binop (operands[1], operands[2], &lo_op1, &hi_op1, + &lo_op2, &hi_op2); + lo_result = gen_lowpart (SImode, operands[0]); + hi_result = gen_highpart (SImode, operands[0]); + + if (lo_op2 == const0_rtx) + { + emit_move_insn (lo_result, lo_op1); + if (!arm_add_operand (hi_op2, SImode)) + hi_op2 = force_reg (SImode, hi_op2); + + emit_insn (gen_addvsi4 (hi_result, hi_op1, hi_op2, operands[3])); + } + else + { + if (!arm_add_operand (lo_op2, SImode)) + lo_op2 = force_reg (SImode, lo_op2); + if (!arm_not_operand (hi_op2, SImode)) + hi_op2 = force_reg (SImode, hi_op2); + + emit_insn (gen_addsi3_compare_op1 (lo_result, lo_op1, lo_op2)); + + if (hi_op2 == const0_rtx) + emit_insn (gen_addsi3_cin_vout_0 (hi_result, hi_op1)); + else if (CONST_INT_P (hi_op2)) + emit_insn (gen_addsi3_cin_vout_imm (hi_result, hi_op1, hi_op2)); + else + emit_insn (gen_addsi3_cin_vout_reg (hi_result, hi_op1, hi_op2)); + + arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); + } DONE; }) +(define_expand "addsi3_cin_vout_reg" + [(parallel + [(set (match_dup 3) + (compare:CC_V + (plus:DI + (plus:DI (match_dup 4) + (sign_extend:DI (match_operand:SI 1 "s_register_operand"))) + (sign_extend:DI (match_operand:SI 2 "s_register_operand"))) + (sign_extend:DI (plus:SI (plus:SI (match_dup 5) (match_dup 1)) + (match_dup 2))))) + (set (match_operand:SI 0 "s_register_operand") + (plus:SI (plus:SI (match_dup 5) (match_dup 1)) + (match_dup 2)))])] + "TARGET_32BIT" + { + operands[3] = gen_rtx_REG (CC_Vmode, CC_REGNUM); + rtx ccin = gen_rtx_REG (CC_Cmode, CC_REGNUM); + operands[4] = gen_rtx_LTU (DImode, ccin, const0_rtx); + operands[5] = gen_rtx_LTU (SImode, ccin, const0_rtx); + } +) + +(define_insn "*addsi3_cin_vout_reg_insn" + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (plus:DI + (plus:DI + (match_operand:DI 3 "arm_carry_operation" "") + (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))) + (sign_extend:DI (match_operand:SI 2 "s_register_operand" "l,r"))) + (sign_extend:DI + (plus:SI (plus:SI (match_operand:SI 4 "arm_carry_operation" "") + (match_dup 1)) + (match_dup 2))))) + (set (match_operand:SI 0 "s_register_operand" "=l,r") + (plus:SI (plus:SI (match_dup 4) (match_dup 1)) + (match_dup 2)))] + "TARGET_32BIT" + "@ + adcs%?\\t%0, %0, %2 + adcs%?\\t%0, %1, %2" + [(set_attr "type" "alus_sreg") + (set_attr "arch" "t2,*") + (set_attr "length" "2,4")] +) + +(define_expand "addsi3_cin_vout_imm" + [(parallel + [(set (match_dup 3) + (compare:CC_V + (plus:DI + (plus:DI (match_dup 4) + (sign_extend:DI (match_operand:SI 1 "s_register_operand"))) + (match_dup 2)) + (sign_extend:DI (plus:SI (plus:SI (match_dup 5) (match_dup 1)) + (match_dup 2))))) + (set (match_operand:SI 0 "s_register_operand") + (plus:SI (plus:SI (match_dup 5) (match_dup 1)) + (match_operand 2 "arm_adcimm_operand")))])] + "TARGET_32BIT" + { + operands[3] = gen_rtx_REG (CC_Vmode, CC_REGNUM); + rtx ccin = gen_rtx_REG (CC_Cmode, CC_REGNUM); + operands[4] = gen_rtx_LTU (DImode, ccin, const0_rtx); + operands[5] = gen_rtx_LTU (SImode, ccin, const0_rtx); + } +) + +(define_insn "*addsi3_cin_vout_imm_insn" + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (plus:DI + (plus:DI + (match_operand:DI 3 "arm_carry_operation" "") + (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r,r"))) + (match_operand 2 "arm_adcimm_operand" "I,K")) + (sign_extend:DI + (plus:SI (plus:SI (match_operand:SI 4 "arm_carry_operation" "") + (match_dup 1)) + (match_dup 2))))) + (set (match_operand:SI 0 "s_register_operand" "=r,r") + (plus:SI (plus:SI (match_dup 4) (match_dup 1)) + (match_dup 2)))] + "TARGET_32BIT" + "@ + adcs%?\\t%0, %1, %2 + sbcs%?\\t%0, %1, #%B2" + [(set_attr "type" "alus_imm")] +) + +(define_expand "addsi3_cin_vout_0" + [(parallel + [(set (match_dup 2) + (compare:CC_V + (plus:DI (match_dup 3) + (sign_extend:DI (match_operand:SI 1 "s_register_operand"))) + (sign_extend:DI (plus:SI (match_dup 4) (match_dup 1))))) + (set (match_operand:SI 0 "s_register_operand") + (plus:SI (match_dup 4) (match_dup 1)))])] + "TARGET_32BIT" + { + operands[2] = gen_rtx_REG (CC_Vmode, CC_REGNUM); + rtx ccin = gen_rtx_REG (CC_Cmode, CC_REGNUM); + operands[3] = gen_rtx_LTU (DImode, ccin, const0_rtx); + operands[4] = gen_rtx_LTU (SImode, ccin, const0_rtx); + } +) + +(define_insn "*addsi3_cin_vout_0_insn" + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (plus:DI + (match_operand:DI 2 "arm_carry_operation" "") + (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))) + (sign_extend:DI (plus:SI + (match_operand:SI 3 "arm_carry_operation" "") + (match_dup 1))))) + (set (match_operand:SI 0 "s_register_operand" "=r") + (plus:SI (match_dup 3) (match_dup 1)))] + "TARGET_32BIT" + "adcs%?\\t%0, %1, #0" + [(set_attr "type" "alus_imm")] +) + (define_expand "uaddvsi4" [(match_operand:SI 0 "s_register_operand") (match_operand:SI 1 "s_register_operand") @@ -770,22 +925,6 @@ (define_insn_and_split "*arm_addsi3" ] ) -(define_insn "adddi3_compareV" - [(set (reg:CC_V CC_REGNUM) - (ne:CC_V - (plus:TI - (sign_extend:TI (match_operand:DI 1 "s_register_operand" "r")) - (sign_extend:TI (match_operand:DI 2 "s_register_operand" "r"))) - (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2))))) - (set (match_operand:DI 0 "s_register_operand" "=&r") - (plus:DI (match_dup 1) (match_dup 2)))] - "TARGET_32BIT" - "adds\\t%Q0, %Q1, %Q2;adcs\\t%R0, %R1, %R2" - [(set_attr "conds" "set") - (set_attr "length" "8") - (set_attr "type" "multiple")] -) - (define_insn "addsi3_compareV_reg" [(set (reg:CC_V CC_REGNUM) (compare:CC_V diff --git a/gcc/testsuite/gcc.dg/builtin-arith-overflow-3.c b/gcc/testsuite/gcc.dg/builtin-arith-overflow-3.c new file mode 100644 index 00000000000..6feae1eb42f --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtin-arith-overflow-3.c @@ -0,0 +1,41 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +static int cnt = 0; + +#define LL_MIN ((long long)(-__LONG_LONG_MAX__ - 1)) + +#define SC1 (LL_MIN + 5) +#define UC1 ((1ULL << (__LONG_LONG_WIDTH__ - 1)) | 5ULL) +#define UC2 (~UC1) + +long long __attribute__ ((noinline, noclone)) +f1 (long long a) +{ + long long x; + if (__builtin_add_overflow (a, SC1, &x)) cnt++; + return x; +} + +unsigned long long __attribute__ ((noinline, noclone)) +f2 (unsigned long long a) +{ + unsigned long long x; + if (__builtin_add_overflow (a, UC1, &x)) + cnt++; + return x; +} + +int main () +{ + if (f1 (-5) != LL_MIN) __builtin_abort (); + if (cnt != 0) __builtin_abort (); + f1 (-6); + if (cnt != 1) __builtin_abort (); + cnt = 0; + if (f2 (UC2) != ~0ULL) __builtin_abort (); + if (cnt != 0) __builtin_abort (); + if (f2 (UC2 + 1) != 0) __builtin_abort (); + if (cnt != 1) __builtin_abort (); + return 0; +} From patchwork Fri Oct 18 19:48:55 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: 1179624 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511313-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="ET19oEaG"; dkim-atps=neutral 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 46vxTs52BZz9sP7 for ; Sat, 19 Oct 2019 06:50:41 +1100 (AEDT) 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=BgGjad+SgohonV7q d0GadSg4z7el5rdH41UvnAi2xLf1y3Qwtc20zJNhSQRP28YtYyODIWEar9qYtYk8 4hmG8+L2L+ogvZuoHiyDk5pwIdPIRVwV1fmBZgay57FRaLVFwcFnYKnLwn7JWqZy Lm02SwrDyLKa2U1RCknkS4REYKI= 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=ZQx9gy5HflaFZA5qEsGZ7Y wlGsI=; b=ET19oEaGCzhdCYFb+A1j9i6cSQqWSFQzkAY1mC3CdQOSXZGn15ED/O aXVqx5Vloy5+ShP+AK4V7luNqop85yM80880dOjE7ZkW8zrzpNLOKIan3noRHzqO NJdBhQw4WvS8i6ABm28mspVlAvaez1sut1KpBq9M9Fd42xIAPjy3k= Received: (qmail 78343 invoked by alias); 18 Oct 2019 19:49:39 -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 78256 invoked by uid 89); 18 Oct 2019 19:49:39 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.4 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= X-HELO: foss.arm.com Received: from Unknown (HELO foss.arm.com) (217.140.110.172) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 18 Oct 2019 19:49:37 +0000 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 EA9951764; Fri, 18 Oct 2019 12:49:28 -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 760BE3F6C4; Fri, 18 Oct 2019 12:49:28 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 24/29] [arm] Improve constant handling for usubvsi4. Date: Fri, 18 Oct 2019 20:48:55 +0100 Message-Id: <20191018194900.34795-25-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 This patch improves the expansion of usubvsi4 by allowing suitable constants to be passed directly. Unlike normal subtraction, either operand may be a constant (and indeed I have seen cases where both can be with LTO enabled). One interesting testcase that improves as a result of this is: unsigned f6 (unsigned a) { unsigned x; return __builtin_sub_overflow (5U, a, &x) ? 0 : x; } Which previously compiled to: rsbs r3, r0, #5 cmp r0, #5 movls r0, r3 movhi r0, #0 but now generates the optimal sequence: rsbs r0, r0, #5 movcc r0, #0 * config/arm/arm.md (usubv4): Delete expansion. (usubvsi4): New pattern. Allow some immediate values for inputs. (usubvdi4): New pattern. --- gcc/config/arm/arm.md | 46 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index e9e0ca925d2..a465bf8e7a3 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -1352,14 +1352,50 @@ (define_expand "subv4" DONE; }) -(define_expand "usubv4" - [(match_operand:SIDI 0 "register_operand") - (match_operand:SIDI 1 "register_operand") - (match_operand:SIDI 2 "register_operand") +(define_expand "usubvsi4" + [(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" { - emit_insn (gen_sub3_compare1 (operands[0], operands[1], operands[2])); + machine_mode mode = CCmode; + 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), + UNSIGNED, &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])) + emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2], + GEN_INT (-INTVAL (operands[2])))); + else if (CONST_INT_P (operands[1])) + { + mode = CC_RSBmode; + emit_insn (gen_rsb_imm_compare (operands[0], operands[1], operands[2], + GEN_INT (~UINTVAL (operands[1])))); + } + else + emit_insn (gen_subsi3_compare1 (operands[0], operands[1], operands[2])); + arm_gen_unlikely_cbranch (LTU, mode, operands[3]); + + DONE; +}) + +(define_expand "usubvdi4" + [(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_subdi3_compare1 (operands[0], operands[1], operands[2])); arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]); DONE; From patchwork Fri Oct 18 19:48:56 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: 1179627 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511316-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="TltGLAhL"; dkim-atps=neutral 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 46vxbv4dDdz9sPJ for ; Sat, 19 Oct 2019 06:55:53 +1100 (AEDT) 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=F5dPRj4d4szYY2Ug BAI9T3J4m3vvLBJA/WSk6I8bhf9Q+EZ17FqZnDac+fKs+MQZlxBpQ5IH9SL5RH58 lpJW97LPnjlt43la9qewOGfMRqXdKhbxqqWepfo4SkVp+m1yMHeWTu1bZQRVGuQ/ 8t57JEFwzWoWgdfllYnzT6NYkrQ= 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=PEvHUpkKpKFKusln+2nyzf /Hwvc=; b=TltGLAhLHzCyYyfByqb2nV02nwEeEVR1u4w0bT/O3aHESiyTGMknKj 2Jc/wpIwfvOW5HXVlFLAQuntagAJ96wsy2GVMhHXPYpPfym2/laCOS7jW5fgoEex XVs0hQnQUkyP/HTgqzHRvdBxH52IdDbiVnDCanp6tP9E8Yri1VkGs= Received: (qmail 112148 invoked by alias); 18 Oct 2019 19:55:39 -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 110622 invoked by uid 89); 18 Oct 2019 19:55:34 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.7 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=18256 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:31 +0000 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iLYLQ-00053M-Ou for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:29 -0400 Received: from [217.140.110.172] (port=42724 helo=foss.arm.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1iLYLQ-0004xm-Hq for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:28 -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 9E6911765; Fri, 18 Oct 2019 12:49:29 -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 2BBB03F6C4; Fri, 18 Oct 2019 12:49:29 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 25/29] [arm] Early expansion of usubvdi4. Date: Fri, 18 Oct 2019 20:48:56 +0100 Message-Id: <20191018194900.34795-26-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 adds early expansion of usubvdi4, allowing us to handle some constants in place, which previously we were unable to do. * config/arm/arm.md (usubvdi4): Allow registers or integers for incoming operands. Early split the calculation into SImode operations. (usubvsi3_borrow): New insn pattern. (usubvsi3_borrow_imm): Likewise. --- gcc/config/arm/arm.md | 113 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 109 insertions(+), 4 deletions(-) diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index a465bf8e7a3..92f1823cdfa 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -1390,13 +1390,81 @@ (define_expand "usubvsi4" (define_expand "usubvdi4" [(match_operand:DI 0 "s_register_operand") - (match_operand:DI 1 "s_register_operand") - (match_operand:DI 2 "s_register_operand") + (match_operand:DI 1 "reg_or_int_operand") + (match_operand:DI 2 "reg_or_int_operand") (match_operand 3 "")] "TARGET_32BIT" { - emit_insn (gen_subdi3_compare1 (operands[0], operands[1], operands[2])); - arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]); + rtx lo_result, hi_result; + rtx lo_op1, hi_op1, lo_op2, hi_op2; + lo_result = gen_lowpart (SImode, operands[0]); + hi_result = gen_highpart (SImode, operands[0]); + machine_mode mode = CCmode; + + 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], DImode), + rtx_mode_t (operands[2], DImode), + UNSIGNED, &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[1])) + { + arm_decompose_di_binop (operands[2], operands[1], &lo_op2, &hi_op2, + &lo_op1, &hi_op1); + if (const_ok_for_arm (INTVAL (lo_op1))) + { + emit_insn (gen_rsb_imm_compare (lo_result, lo_op1, lo_op2, + GEN_INT (~UINTVAL (lo_op1)))); + /* We could potentially use RSC here in Arm state, but not + in Thumb, so it's probably not worth the effort of handling + this. */ + hi_op1 = force_reg (SImode, hi_op1); + mode = CC_RSBmode; + goto highpart; + } + operands[1] = force_reg (DImode, operands[1]); + } + + arm_decompose_di_binop (operands[1], operands[2], &lo_op1, &hi_op1, + &lo_op2, &hi_op2); + if (lo_op2 == const0_rtx) + { + emit_move_insn (lo_result, lo_op1); + if (!arm_add_operand (hi_op2, SImode)) + hi_op2 = force_reg (SImode, hi_op2); + emit_insn (gen_usubvsi4 (hi_result, hi_op1, hi_op2, operands[3])); + DONE; + } + + if (CONST_INT_P (lo_op2) && !arm_addimm_operand (lo_op2, SImode)) + lo_op2 = force_reg (SImode, lo_op2); + if (CONST_INT_P (lo_op2)) + emit_insn (gen_cmpsi2_addneg (lo_result, lo_op1, lo_op2, + GEN_INT (-INTVAL (lo_op2)))); + else + emit_insn (gen_subsi3_compare1 (lo_result, lo_op1, lo_op2)); + + highpart: + if (!arm_not_operand (hi_op2, SImode)) + hi_op2 = force_reg (SImode, hi_op2); + rtx ccreg = gen_rtx_REG (mode, CC_REGNUM); + if (CONST_INT_P (hi_op2)) + emit_insn (gen_usubvsi3_borrow_imm (hi_result, hi_op1, hi_op2, + GEN_INT (UINTVAL (hi_op2) & 0xffffffff), + gen_rtx_LTU (SImode, ccreg, const0_rtx), + gen_rtx_LTU (DImode, ccreg, + const0_rtx))); + else + emit_insn (gen_usubvsi3_borrow (hi_result, hi_op1, hi_op2, + gen_rtx_LTU (SImode, ccreg, const0_rtx), + gen_rtx_LTU (DImode, ccreg, const0_rtx))); + arm_gen_unlikely_cbranch (LTU, CC_Bmode, operands[3]); DONE; }) @@ -1825,6 +1893,43 @@ (define_insn "rscsi3_out_scratch" (set_attr "type" "alus_imm")] ) +(define_insn "usubvsi3_borrow" + [(set (reg:CC_B CC_REGNUM) + (compare:CC_B + (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r")) + (plus:DI (match_operand:DI 4 "arm_borrow_operation" "") + (zero_extend:DI + (match_operand:SI 2 "s_register_operand" "l,r"))))) + (set (match_operand:SI 0 "s_register_operand" "=l,r") + (minus:SI (match_dup 1) + (plus:SI (match_operand:SI 3 "arm_borrow_operation" "") + (match_dup 2))))] + "TARGET_32BIT" + "sbcs%?\\t%0, %1, %2" + [(set_attr "conds" "set") + (set_attr "arch" "t2,*") + (set_attr "length" "2,4")] +) + +(define_insn "usubvsi3_borrow_imm" + [(set (reg:CC_B CC_REGNUM) + (compare:CC_B + (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r,r")) + (plus:DI (match_operand:DI 5 "arm_borrow_operation" "") + (match_operand:DI 3 "const_int_operand" "n,n")))) + (set (match_operand:SI 0 "s_register_operand" "=r,r") + (minus:SI (match_dup 1) + (plus:SI (match_operand:SI 4 "arm_borrow_operation" "") + (match_operand:SI 2 "arm_adcimm_operand" "I,K"))))] + "TARGET_32BIT + && (UINTVAL (operands[2]) & 0xffffffff) == UINTVAL (operands[3])" + "@ + sbcs%?\\t%0, %1, %2 + adcs%?\\t%0, %1, #%B2" + [(set_attr "conds" "set") + (set_attr "type" "alus_imm")] +) + (define_expand "subsf3" [(set (match_operand:SF 0 "s_register_operand") (minus:SF (match_operand:SF 1 "s_register_operand") 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: 1179639 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511327-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="UpF/BqB/"; dkim-atps=neutral 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 46vxff1yxsz9sPK for ; Sat, 19 Oct 2019 06:58:18 +1100 (AEDT) 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=dhYv+IeBGl9TCz0S m8YVXlndI7p73muS+J1oT5ooeofR/VF6bdjy9cxYVTUOpPwQtO9lMlvLFWQCMspa /N+stX18MQlSwTMaYMUKLo5kIIrw6XyfAliNuCao813JvLEM5lLfXd1IhV0v+GKD z8Iwsd7qrE4sFRxJgyqOuAUTk2k= 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=UpF/BqB/F3D349x6DEC5t3HUWEwUr7iHlycumX/kftFzBMVqlSbNRj y9TOAtoTRvhKFwAbI4fRCrDiu4TYibo24Fm9CyT/xMlzx0myqvKYjxpwIxYmZbO3 zZxK6/8Nzda9BPAERjDx7JlQoXTmGzYJHCw3X4N936aWmWqMnX8x4= 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") From patchwork Fri Oct 18 19:48:58 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: 1179632 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511320-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="M25fIX1S"; dkim-atps=neutral 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 46vxd00kp1z9sP7 for ; Sat, 19 Oct 2019 06:56:51 +1100 (AEDT) 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=Wjegb0LoiWlwKhLR jwFeWnXSOL3FXXYlMiE5Kt5O8aALenMxePaIRhHcULFdNMg9OsG1qSx3e0aiqr30 CxjAxbj3uSx5Sg2MqmcTrY+upuChKU+XV3Jhoy24T1SYut2HH2V47O88ErFH3kvz ltw7gz592IZUAMQ0PaKCj+uVtY8= 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=x86ysXMDqtO1+oPbsbRlZh hRHpc=; b=M25fIX1SCPSsbQiWMKh9QL2F79mAU2t16sTq36Da9dFf7wC/dJQmNE j4ooGiwNZpT9ncFUVCZXQGrx3VG9bmFKN/Kn/9fpQlsXdcOfHVq65kXYQuzYDkpv dkTpVd1Jrd5GrZM66ggoyZbhstqEMR0wm2pOJvyEry/i3GvGl8QcM= Received: (qmail 113029 invoked by alias); 18 Oct 2019 19:55:41 -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 110801 invoked by uid 89); 18 Oct 2019 19:55:37 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.5 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_NUMSUBJECT autolearn=ham version=3.3.1 spammy=SIGNED 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:34 +0000 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iLYLR-00054D-L4 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-Dk for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:29 -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 05A8E15A1; Fri, 18 Oct 2019 12:49:31 -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 8724A3F6C4; Fri, 18 Oct 2019 12:49:30 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 27/29] [arm] Early expansion of subvdi4 Date: Fri, 18 Oct 2019 20:48:58 +0100 Message-Id: <20191018194900.34795-28-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 adds early expansion of subvdi4. The expansion sequence is broadly based on the expansion of usubvdi4. * config/arm/arm.md (subvdi4): Decompose calculation into 32-bit operations. (subdi3_compare1): Delete pattern. (subvsi3_borrow): New insn pattern. (subvsi3_borrow_imm): Likewise. --- gcc/config/arm/arm.md | 131 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 114 insertions(+), 17 deletions(-) diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 05b735cfccd..5a8175ff8b0 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -1395,12 +1395,79 @@ (define_expand "subvsi4" (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:DI 1 "reg_or_int_operand") + (match_operand:DI 2 "reg_or_int_operand") (match_operand 3 "")] "TARGET_32BIT" { - emit_insn (gen_subdi3_compare1 (operands[0], operands[1], operands[2])); + rtx lo_result, hi_result; + rtx lo_op1, hi_op1, lo_op2, hi_op2; + lo_result = gen_lowpart (SImode, operands[0]); + hi_result = gen_highpart (SImode, operands[0]); + machine_mode mode = CCmode; + + 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], DImode), + rtx_mode_t (operands[2], DImode), + 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[1])) + { + arm_decompose_di_binop (operands[2], operands[1], &lo_op2, &hi_op2, + &lo_op1, &hi_op1); + if (const_ok_for_arm (INTVAL (lo_op1))) + { + emit_insn (gen_rsb_imm_compare (lo_result, lo_op1, lo_op2, + GEN_INT (~UINTVAL (lo_op1)))); + /* We could potentially use RSC here in Arm state, but not + in Thumb, so it's probably not worth the effort of handling + this. */ + hi_op1 = force_reg (SImode, hi_op1); + mode = CC_RSBmode; + goto highpart; + } + operands[1] = force_reg (DImode, operands[1]); + } + + arm_decompose_di_binop (operands[1], operands[2], &lo_op1, &hi_op1, + &lo_op2, &hi_op2); + if (lo_op2 == const0_rtx) + { + emit_move_insn (lo_result, lo_op1); + if (!arm_add_operand (hi_op2, SImode)) + hi_op2 = force_reg (SImode, hi_op2); + emit_insn (gen_subvsi4 (hi_result, hi_op1, hi_op2, operands[3])); + DONE; + } + + if (CONST_INT_P (lo_op2) && !arm_addimm_operand (lo_op2, SImode)) + lo_op2 = force_reg (SImode, lo_op2); + if (CONST_INT_P (lo_op2)) + emit_insn (gen_cmpsi2_addneg (lo_result, lo_op1, lo_op2, + GEN_INT (-INTVAL (lo_op2)))); + else + emit_insn (gen_subsi3_compare1 (lo_result, lo_op1, lo_op2)); + + highpart: + if (!arm_not_operand (hi_op2, SImode)) + hi_op2 = force_reg (SImode, hi_op2); + rtx ccreg = gen_rtx_REG (mode, CC_REGNUM); + if (CONST_INT_P (hi_op2)) + emit_insn (gen_subvsi3_borrow_imm (hi_result, hi_op1, hi_op2, + gen_rtx_LTU (SImode, ccreg, const0_rtx), + gen_rtx_LTU (DImode, ccreg, + const0_rtx))); + else + emit_insn (gen_subvsi3_borrow (hi_result, hi_op1, hi_op2, + gen_rtx_LTU (SImode, ccreg, const0_rtx), + gen_rtx_LTU (DImode, ccreg, const0_rtx))); arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); DONE; @@ -1523,20 +1590,6 @@ (define_expand "usubvdi4" DONE; }) -(define_insn "subdi3_compare1" - [(set (reg:CC CC_REGNUM) - (compare:CC - (match_operand:DI 1 "s_register_operand" "r") - (match_operand:DI 2 "s_register_operand" "r"))) - (set (match_operand:DI 0 "s_register_operand" "=&r") - (minus:DI (match_dup 1) (match_dup 2)))] - "TARGET_32BIT" - "subs\\t%Q0, %Q1, %Q2;sbcs\\t%R0, %R1, %R2" - [(set_attr "conds" "set") - (set_attr "length" "8") - (set_attr "type" "multiple")] -) - (define_insn "subsi3_compare1" [(set (reg:CC CC_REGNUM) (compare:CC @@ -2016,6 +2069,50 @@ (define_insn "usubvsi3_borrow_imm" (set_attr "type" "alus_imm")] ) +(define_insn "subvsi3_borrow" + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (minus:DI + (minus:DI + (sign_extend:DI (match_operand:SI 1 "s_register_operand" "0,r")) + (sign_extend:DI (match_operand:SI 2 "s_register_operand" "l,r"))) + (match_operand:DI 4 "arm_borrow_operation" "")) + (sign_extend:DI + (minus:SI (minus:SI (match_dup 1) (match_dup 2)) + (match_operand:SI 3 "arm_borrow_operation" ""))))) + (set (match_operand:SI 0 "s_register_operand" "=l,r") + (minus:SI (minus:SI (match_dup 1) (match_dup 2)) + (match_dup 3)))] + "TARGET_32BIT" + "sbcs%?\\t%0, %1, %2" + [(set_attr "conds" "set") + (set_attr "arch" "t2,*") + (set_attr "length" "2,4")] +) + +(define_insn "subvsi3_borrow_imm" + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (minus:DI + (minus:DI + (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r,r")) + (match_operand 2 "arm_adcimm_operand" "I,K")) + (match_operand:DI 4 "arm_borrow_operation" "")) + (sign_extend:DI + (minus:SI (minus:SI (match_dup 1) (match_dup 2)) + (match_operand:SI 3 "arm_borrow_operation" ""))))) + (set (match_operand:SI 0 "s_register_operand" "=r,r") + (minus:SI (minus:SI (match_dup 1) (match_dup 2)) + (match_dup 3)))] + "TARGET_32BIT + && INTVAL (operands[2]) == ARM_SIGN_EXTEND (INTVAL (operands[2]))" + "@ + sbcs%?\\t%0, %1, %2 + adcs%?\\t%0, %1, #%B2" + [(set_attr "conds" "set") + (set_attr "type" "alus_imm")] +) + (define_expand "subsf3" [(set (match_operand:SF 0 "s_register_operand") (minus:SF (match_operand:SF 1 "s_register_operand") From patchwork Fri Oct 18 19:48:59 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: 1179637 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511325-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="hgkPo9iw"; dkim-atps=neutral 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 46vxfB2V7Lz9sP7 for ; Sat, 19 Oct 2019 06:57:54 +1100 (AEDT) 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=nrPx/tBUnW5zH83G FakPNvI4LEMoDv8IYmptUJn5DhN1/G11jinMY3WM9MmVlU/guT3NFSwzKJA7icYE bWzCaaGYjcmxAkRTTfYjLWTxQNMsB34JNidyzSaWypTJEC+GOiSJi1mxP887Pj9f oMNL1/EoovDEYAczAhpZoAfeTt4= 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=TqRx/PjuwJ+ESzeZDu71JU 9buGk=; b=hgkPo9iwfH/57EWci4TEUTBJDPK/7IF0sjgfw2Gb3MXistCt7PjIon 2gMneIM3wYAR8r2NSIozySvxVQqA7eb/qj7IBbiikJAA9i6OXvjobfJJDl0DleVr C45/117n8uARgI4UmO4RL9ubHXZLASD8xWB+N8HhsoiVMFJIzs54I= Received: (qmail 114954 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 110614 invoked by uid 89); 18 Oct 2019 19:55:34 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.7 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= 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:31 +0000 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iLYLR-000542-9R for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:30 -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-4Q for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:29 -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 AD8F21766; Fri, 18 Oct 2019 12:49:31 -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 3AF5B3F6C4; Fri, 18 Oct 2019 12:49:31 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 28/29] [arm] Improvements to negvsi4 and negvdi4. Date: Fri, 18 Oct 2019 20:48:59 +0100 Message-Id: <20191018194900.34795-29-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 The generic expansion code for negv does not try the subv patterns, but instead emits a sub and a compare separately. Fortunately, the patterns can make use of the new subv operations, so just call those. We can also rewrite this using an iterator to simplify things further. Finally, we can now make negvdi4 work on Thumb2 as well as Arm. * config/arm/arm.md (negv3): New expansion rule. (negvsi3, negvdi3): Delete. (negdi2_compare): Delete. --- gcc/config/arm/arm.md | 41 +++++------------------------------------ 1 file changed, 5 insertions(+), 36 deletions(-) diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 5a8175ff8b0..7ef0c16580d 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -4581,48 +4581,17 @@ (define_insn "udivsi3" ;; Unary arithmetic insns -(define_expand "negvsi3" - [(match_operand:SI 0 "register_operand") - (match_operand:SI 1 "register_operand") +(define_expand "negv3" + [(match_operand:SIDI 0 "s_register_operand") + (match_operand:SIDI 1 "s_register_operand") (match_operand 2 "")] "TARGET_32BIT" { - emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1])); - arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]); - - DONE; -}) - -(define_expand "negvdi3" - [(match_operand:DI 0 "s_register_operand") - (match_operand:DI 1 "s_register_operand") - (match_operand 2 "")] - "TARGET_ARM" -{ - emit_insn (gen_negdi2_compare (operands[0], operands[1])); - arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]); - + emit_insn (gen_subv4 (operands[0], const0_rtx, operands[1], + operands[2])); DONE; }) - -(define_insn "negdi2_compare" - [(set (reg:CC CC_REGNUM) - (compare:CC - (const_int 0) - (match_operand:DI 1 "register_operand" "r,r"))) - (set (match_operand:DI 0 "register_operand" "=&r,&r") - (minus:DI (const_int 0) (match_dup 1)))] - "TARGET_ARM" - "@ - rsbs\\t%Q0, %Q1, #0;rscs\\t%R0, %R1, #0 - rsbs\\t%Q0, %Q1, #0;sbcs\\t%R0, %R1, %R1, lsl #1" - [(set_attr "conds" "set") - (set_attr "arch" "a,t2") - (set_attr "length" "8") - (set_attr "type" "multiple")] -) - (define_expand "negsi2" [(set (match_operand:SI 0 "s_register_operand") (neg:SI (match_operand:SI 1 "s_register_operand")))] From patchwork Fri Oct 18 19:49:00 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: 1179650 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511338-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="h2QtGXbc"; dkim-atps=neutral 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 46vxjc1jCqz9sP7 for ; Sat, 19 Oct 2019 07:00:52 +1100 (AEDT) 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=eT3bZvrkHeySyO0I Tu67epPgT+EGX2f2K/M81jYDFzFye5kCUcUWV66XmUCPZ/leBgpe4HSvsSBSJKWB UT8efPQZlQlNzCBAPQVaucwyrrIxx/NZZFIoYS4+LHC+7TUAgp5CH37/ySzDNO5D A9SGmhTZbZbr9dQ7Kk9NH+yyqQw= 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=Oew5I/UpL7RstMVxHjZ+Tx mOZWM=; b=h2QtGXbcupt9bztu7bl7LKOAXfDOS32y1pTPfHcHu49Nt3kkoUv6JQ S4UxZQm4Y8reUBDJMJSoyOGCM9+UXuQZ7sV41NgJvm7a+NkasxxJNEngU+vAv15M Ff4vvqs+pc99S59XA3WzbctbcTFOo+8JybKBiSd2dWYe/iXP2kvV0= Received: (qmail 122250 invoked by alias); 18 Oct 2019 19:56:39 -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 116108 invoked by uid 89); 18 Oct 2019 19:55:53 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-19.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_NUMSUBJECT, SPF_FAIL autolearn=ham version=3.3.1 spammy=HX-Languages-Length:994 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:52 +0000 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iLYLd-0005AA-3N for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:41 -0400 Received: from [217.140.110.172] (port=42768 helo=foss.arm.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1iLYLc-00055X-TY for gcc-patches@gcc.gnu.org; Fri, 18 Oct 2019 15:55:41 -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 614031767; Fri, 18 Oct 2019 12:49:32 -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 E2C663F6C4; Fri, 18 Oct 2019 12:49:31 -0700 (PDT) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 29/29] [arm] Fix testsuite nit when compiling for thumb2 Date: Fri, 18 Oct 2019 20:49:00 +0100 Message-Id: <20191018194900.34795-30-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 thumb2 we now generate a NEGS instruction rather than RSBS, so this test needs updating. * gcc.target/arm/negdi-3.c: Update expected output to allow NEGS. --- gcc/testsuite/gcc.target/arm/negdi-3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/testsuite/gcc.target/arm/negdi-3.c b/gcc/testsuite/gcc.target/arm/negdi-3.c index 76ddf49fc0d..1520e9c65df 100644 --- a/gcc/testsuite/gcc.target/arm/negdi-3.c +++ b/gcc/testsuite/gcc.target/arm/negdi-3.c @@ -8,10 +8,10 @@ signed long long negdi_zero_extendsidi (unsigned int x) } /* Expected output: - rsbs r0, r0, #0 + rsbs r0, r0, #0 (arm) | negs r0, r0 (thumb2) sbc r1, r1, r1 */ -/* { dg-final { scan-assembler-times "rsb" 1 } } */ +/* { dg-final { scan-assembler-times "rsbs|negs" 1 } } */ /* { dg-final { scan-assembler-times "sbc" 1 } } */ /* { dg-final { scan-assembler-times "mov" 0 } } */ /* { dg-final { scan-assembler-times "rsc" 0 } } */