From patchwork Tue Dec 20 21:29:14 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernd Schmidt X-Patchwork-Id: 88639 Delivered-To: patch@linaro.org Received: by 10.140.20.101 with SMTP id 92csp1942202qgi; Tue, 20 Dec 2016 13:29:46 -0800 (PST) X-Received: by 10.84.134.131 with SMTP id 3mr2325666plh.89.1482269385982; Tue, 20 Dec 2016 13:29:45 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id p123si23833067pfg.149.2016.12.20.13.29.45 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 20 Dec 2016 13:29:45 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-444882-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-444882-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-444882-patch=linaro.org@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to:cc :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=Aap0Q9OuLy/auoOtjtjf87lD/cGQ8Yb1gB8GruTuvdpGEBD/KO +WQYhlzGdsRabCdBorVh+SsbGmMs9jOqUsG20vFql0vxshhGzmlYA+7ZQ8jXgYpy VxVcp87IXD7IMNI5KLnqbT44dv9H/Lp/ejQPwWMVezYBd+JsPNF1/mi74= 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:to:cc :from:subject:message-id:date:mime-version:content-type; s= default; bh=L2u4748I9315PAXFSRauTKoA/X0=; b=Gq+t05VXN8LmbEwVRkvv x8TI8n81Ut3gS01TEe5LgYbMLKogOaGOn5+W9U9sxNfy0PQGaVMtZmJRLWk47RkU 2KBYy+thF6r14cLZ3GZXCCgMznGFhkeqpV/xP1BOM5Rlpy1mbtUIhw+eVklIgKEm hrYCLOj5Vag0pCegjYCstIo= Received: (qmail 37670 invoked by alias); 20 Dec 2016 21:29:30 -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 37653 invoked by uid 89); 20 Dec 2016 21:29:29 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-4.2 required=5.0 tests=BAYES_00, KAM_ASCII_DIVIDERS, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=*lea, HImode, himode, revisit X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 20 Dec 2016 21:29:18 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E88084E34D; Tue, 20 Dec 2016 21:29:16 +0000 (UTC) Received: from localhost.localdomain (ovpn-116-118.ams2.redhat.com [10.36.116.118]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id uBKLTFUP010286; Tue, 20 Dec 2016 16:29:15 -0500 To: GCC Patches , Uros Bizjak Cc: Segher Boessenkool From: Bernd Schmidt Subject: [i386] New lea patterns for PR71321 Message-ID: Date: Tue, 20 Dec 2016 22:29:14 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.5.1 MIME-Version: 1.0 X-IsSubscribed: yes The problem here is that we don't have complete coverage of lea patterns for HImode/QImode: the combiner can't recognize a (plus (ashift reg 2) reg) pattern it builds. My first idea was to canonicalize ASHIFT by constant inside PLUS to MULT. The docs say that this is done only inside a MEM context, but that seems misguided considering the existence of lea patterns. Maybe that's something to revisit for gcc-8. In the meantime, the patch below is more like a minimal fix, and it seems to produce better results at the moment anyway. Bootstrapped and tested on x86_64-linux. Ok? Bernd PR target/71321 * config/i386/i386.md (lea_general_2b, lea_general_3b): New patterns. * config/i386/predicates.md (const123_operand): New. PR target/71321 * gcc.target/i386/pr71321.c: New test. Index: gcc/config/i386/i386.md =================================================================== --- gcc/config/i386/i386.md (revision 243548) +++ gcc/config/i386/i386.md (working copy) @@ -6266,6 +6266,27 @@ (define_insn_and_split "*lea_gener [(set_attr "type" "lea") (set_attr "mode" "SI")]) +(define_insn_and_split "*lea_general_2b" + [(set (match_operand:SWI12 0 "register_operand" "=r") + (plus:SWI12 + (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l") + (match_operand 2 "const123_operand" "n")) + (match_operand:SWI12 3 "nonmemory_operand" "ri")))] + "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" + "#" + "&& reload_completed" + [(set (match_dup 0) + (plus:SI + (ashift:SI (match_dup 1) (match_dup 2)) + (match_dup 3)))] +{ + operands[0] = gen_lowpart (SImode, operands[0]); + operands[1] = gen_lowpart (SImode, operands[1]); + operands[3] = gen_lowpart (SImode, operands[3]); +} + [(set_attr "type" "lea") + (set_attr "mode" "SI")]) + (define_insn_and_split "*lea_general_3" [(set (match_operand:SWI12 0 "register_operand" "=r") (plus:SWI12 @@ -6284,6 +6305,32 @@ (define_insn_and_split "*lea_gener (match_dup 3)) (match_dup 4)))] { + operands[0] = gen_lowpart (SImode, operands[0]); + operands[1] = gen_lowpart (SImode, operands[1]); + operands[3] = gen_lowpart (SImode, operands[3]); + operands[4] = gen_lowpart (SImode, operands[4]); +} + [(set_attr "type" "lea") + (set_attr "mode" "SI")]) + +(define_insn_and_split "*lea_general_3b" + [(set (match_operand:SWI12 0 "register_operand" "=r") + (plus:SWI12 + (plus:SWI12 + (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l") + (match_operand 2 "const123_operand" "n")) + (match_operand:SWI12 3 "register_operand" "r")) + (match_operand:SWI12 4 "immediate_operand" "i")))] + "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" + "#" + "&& reload_completed" + [(set (match_dup 0) + (plus:SI + (plus:SI + (ashift:SI (match_dup 1) (match_dup 2)) + (match_dup 3)) + (match_dup 4)))] +{ operands[0] = gen_lowpart (SImode, operands[0]); operands[1] = gen_lowpart (SImode, operands[1]); operands[3] = gen_lowpart (SImode, operands[3]); Index: gcc/config/i386/predicates.md =================================================================== --- gcc/config/i386/predicates.md (revision 243548) +++ gcc/config/i386/predicates.md (working copy) @@ -765,6 +765,14 @@ (define_predicate "const248_operand" return i == 2 || i == 4 || i == 8; }) +;; Match 1, 2, or 3. Used for lea shift amounts. +(define_predicate "const123_operand" + (match_code "const_int") +{ + HOST_WIDE_INT i = INTVAL (op); + return i == 1 || i == 2 || i == 3; +}) + ;; Match 2, 3, 6, or 7 (define_predicate "const2367_operand" (match_code "const_int") Index: gcc/testsuite/gcc.target/i386/pr71321.c =================================================================== --- gcc/testsuite/gcc.target/i386/pr71321.c (nonexistent) +++ gcc/testsuite/gcc.target/i386/pr71321.c (working copy) @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +typedef unsigned char uint8_t; +typedef unsigned int uint32_t; + +unsigned cvt_to_2digit(uint8_t i, uint8_t base) +{ + return ((i / base) | (uint32_t)(i % base)<<8); +} +unsigned cvt_to_2digit_ascii(uint8_t i) +{ + return cvt_to_2digit(i, 10) + 0x0a3030; +} +/* { dg-final { scan-assembler-times "lea.\t\\(%\[0-9a-z\]+,%\[0-9a-z\]+,4" 3 } } */ +/* { dg-final { scan-assembler-times "lea.\t\\(%\[0-9a-z\]+,%\[0-9a-z\]+,8" 1 } } */