From patchwork Wed Dec 2 01:55:17 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Segher Boessenkool X-Patchwork-Id: 551137 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 2F9C5140316 for ; Wed, 2 Dec 2015 12:55:46 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=Pxop16Ro; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; q=dns; s=default; b=eslw47Qfb5hT s2bbbnJPDKFRjLOWCNx+yPpCm8+Z1Bqba57T8gfZoY8k7sTC7bs9vOuJCPrNN6pk PXKng6p6wPiJKGXkP//XylrNfIgzNTH+h6LQvZp+z50foJ5MsI5fDorqwKp09d7E kBMo0RxtdXUK88YM0mZG7zbfRrLtQIs= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; s=default; bh=alJEGH9ZTG9dCJCAnK zmoeJv2Kc=; b=Pxop16RoOrXtGbbUI03pMKYqEI7JEtL403JK0qcHPVS6B1I4Xe 1+JH8kYk0i9p9jhcoLWClQVNuyzI7sb/v+GHLW9SNi5GDOs3HUr1MYtXD5JiuZ5h 6gTVyqQLs7cbX2yd296vmiKhnGxZVm4zu9rVQ0VvQb3kY9jTUXTcD26w0= Received: (qmail 123435 invoked by alias); 2 Dec 2015 01:55: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 123057 invoked by uid 89); 2 Dec 2015 01:55:35 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.2 required=5.0 tests=AWL, BAYES_00, KAM_LAZY_DOMAIN_SECURITY, T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: gcc1-power7.osuosl.org Received: from gcc1-power7.osuosl.org (HELO gcc1-power7.osuosl.org) (140.211.15.137) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 02 Dec 2015 01:55:34 +0000 Received: by gcc1-power7.osuosl.org (Postfix, from userid 10019) id 26ED21C03F1; Wed, 2 Dec 2015 01:55:31 +0000 (UTC) From: Segher Boessenkool To: gcc-patches@gcc.gnu.org Cc: dje.gcc@gmail.com, Segher Boessenkool Subject: [PATCH] rs6000: Optimise SImode cstore on 64-bit Date: Wed, 2 Dec 2015 01:55:17 +0000 Message-Id: <848d1b5499f57ba7bd5271312f28eacdd91777ad.1449020085.git.segher@kernel.crashing.org> X-IsSubscribed: yes On 64-bit we can do comparisons of 32-bit values by extending those values to 64-bit, subtracting them, and then getting the high bit of the result. For registers this is always cheaper than using the carry bit sequence; and if the comparison involves a constant, this is cheaper than the sequence we previously generated in half of the cases (and the same cost in the other cases). After this, the only sequence left that is using the mfcr insn is the one doing signed comparison of Pmode registers. Testing in progress. Okay for trunk if that succeeds? Segher 2015-12-01 Segher Boessenkool * config/rs6000/rs6000.md (cstore_si_as_di): New expander. (cstore4): Use it. --- gcc/config/rs6000/rs6000.md | 52 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index a500d67..a599372 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -10564,6 +10564,53 @@ (define_expand "cstore4_unsigned" DONE; }) +(define_expand "cstore_si_as_di" + [(use (match_operator 1 "unsigned_comparison_operator" + [(match_operand:SI 2 "gpc_reg_operand") + (match_operand:SI 3 "reg_or_short_operand")])) + (clobber (match_operand:SI 0 "register_operand"))] + "" +{ + int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0; + enum rtx_code cond_code = signed_condition (GET_CODE (operands[1])); + + rtx op1 = gen_reg_rtx (DImode); + rtx op2 = gen_reg_rtx (DImode); + convert_move (op1, operands[2], uns_flag); + convert_move (op2, operands[3], uns_flag); + + if (cond_code == GT || cond_code == LE) + { + cond_code = swap_condition (cond_code); + std::swap (op1, op2); + } + + rtx tmp = gen_reg_rtx (DImode); + rtx tmp2 = gen_reg_rtx (DImode); + rtx tmp3 = gen_reg_rtx (DImode); + emit_insn (gen_subdi3 (tmp, op1, op2)); + emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63))); + emit_insn (gen_anddi3 (tmp3, tmp2, const1_rtx)); + + rtx tmp4; + switch (cond_code) + { + default: + gcc_unreachable (); + case LT: + tmp4 = tmp3; + break; + case GE: + tmp4 = gen_reg_rtx (DImode); + emit_insn (gen_xordi3 (tmp4, tmp3, const1_rtx)); + break; + } + + convert_move (operands[0], tmp4, 1); + + DONE; +}) + (define_expand "cstore4_signed_imm" [(use (match_operator 1 "signed_comparison_operator" [(match_operand:GPR 2 "gpc_reg_operand") @@ -10688,6 +10735,11 @@ (define_expand "cstore4" emit_insn (gen_cstore4_unsigned (operands[0], operands[1], operands[2], operands[3])); + /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */ + else if (mode == SImode && Pmode == DImode) + emit_insn (gen_cstore_si_as_di (operands[0], operands[1], + operands[2], operands[3])); + /* For signed comparisons against a constant, we can do some simple bit-twiddling. */ else if (signed_comparison_operator (operands[1], VOIDmode)