From patchwork Tue May 10 15:41:48 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Enkovich X-Patchwork-Id: 620708 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 3r43S23Vy1z9t3n for ; Wed, 11 May 2016 01:43:12 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=MAwbLPsl; 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:date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; q=dns; s=default; b=Uzcyy2r7HxErXTQE1 q6a0rxzMuAaFutGwbT5rWNjG5d+JYWQ8fypZOml3rgNo754BMgei9ZKXJWSW9vNz 9Wwvr9LHjxW1m2mPN0d8BGwVyxvzzuVpqTMExuA06IAye+/VbDfQJxvcoN1tJ64X k/sUFm7QJEVBEUrDJNBA6qN8Yk= 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:date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=default; bh=Flho/sRnX/ozqWX/+6c5Jk/ Z1n4=; b=MAwbLPslUeRgMzsZp4Q0GQKAHYY221tuqH6Ca2Bpz1vLQORdtA8AfiL xEFVSQ494a1VU8vJTQOZJwwLUZdU/ql39+VomE7Ryz0pNXsghA2Q7X6aJ2spAuLb mfn1FnXshczJxizlpcGjzmErIOo3UPq/XJ+cnQ+L4FvTGdinh54c= Received: (qmail 33689 invoked by alias); 10 May 2016 15:43: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 33649 invoked by uid 89); 10 May 2016 15:43:03 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=gen_rtvec, stv X-HELO: mail-ig0-f195.google.com Received: from mail-ig0-f195.google.com (HELO mail-ig0-f195.google.com) (209.85.213.195) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Tue, 10 May 2016 15:42:52 +0000 Received: by mail-ig0-f195.google.com with SMTP id kj7so1542631igb.1 for ; Tue, 10 May 2016 08:42:52 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=SyU8q9bVk5z2h/D/75KbyG8wTrlLTbdhEMFjhB7H72M=; b=E+BZU/YLkR/9yYCCzY3o1F0pZy8c4tpEP9TcpuWpxvTXp2Zh4Rs4lJ/Jj9KxkrovOh HR6XkuFFdmvPsjBGUnDxe7Y8sAgSHxZ36VRx1gZg9Ni3Sn2EczAwJCn1Nfx33KJzg/b0 Xw6h3V9TPD2NeV1COub9U5JVBheWNehPGVW50j/1nceLwW7jY1tbx5vt34OmJ9n48wUB 6lOW6tCT9qG0qR6Wb6CCKqZmS+767K5ZWFdCR8fl95jZdSBT93cuudt8UfISE1RLl8c3 yzw2h+TAjOIBbh4UNWzt/D1u+Ntcb3M++Ip9LUfqUzcMFdTz95/f/OBANhOhr7NCnh+9 UHNw== X-Gm-Message-State: AOPr4FUily353UC1+yHzTFP/LRrcw+/apgsz+p7F1H2G1w06UzDbpXEBm1ib3HxAnStVtQ== X-Received: by 10.50.228.175 with SMTP id sj15mr18100829igc.35.1462894970824; Tue, 10 May 2016 08:42:50 -0700 (PDT) Received: from msticlxl57.ims.intel.com (irdmzpr02-ext.ir.intel.com. [192.198.151.37]) by smtp.gmail.com with ESMTPSA id g186sm1268949iof.27.2016.05.10.08.42.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 10 May 2016 08:42:50 -0700 (PDT) Date: Tue, 10 May 2016 18:41:48 +0300 From: Ilya Enkovich To: Uros Bizjak Cc: "gcc-patches@gcc.gnu.org" , "H.J. Lu" Subject: Re: [PATCH, i386, PR target/70799, 1/2] Support constants in STV pass (DImode) Message-ID: <20160505120325.GA46462@msticlxl57.ims.intel.com> References: <20160429154219.GC6099@msticlxl57.ims.intel.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes On 02 May 10:50, Uros Bizjak wrote: > On Fri, Apr 29, 2016 at 5:42 PM, Ilya Enkovich wrote: > > Hi, > > > > As the first part of PR70799 fix I'd like to add constants support for > > DI-STV pass (which is also related to PR70763). This patch adds CONST_INT > > support as insn operands and extends cost model accordingly. > > > > Bootstrapped and regtested on x86_64-unknown-linux-gnu{-m32}. OK for trunk? > > > > Thanks, > > Ilya > > -- > > gcc/ > > > > 2016-04-29 Ilya Enkovich > > > > PR target/70799 > > PR target/70763 > > * config/i386/i386.c (dimode_scalar_to_vector_candidate_p): Allow > > integer constants. > > (dimode_scalar_chain::vector_const_cost): New. > > (dimode_scalar_chain::compute_convert_gain): Handle constants. > > (dimode_scalar_chain::convert_op): Likewise. > > (dimode_scalar_chain::convert_insn): Likewise. > > > > gcc/testsuite/ > > > > 2016-04-29 Ilya Enkovich > > > > * gcc.target/i386/pr70799-1.c: New test. > >> @@ -3639,6 +3675,22 @@ dimode_scalar_chain::convert_op (rtx *op, rtx_insn *insn) > > } > > *op = gen_rtx_SUBREG (V2DImode, *op, 0); > > } > > + else if (CONST_INT_P (*op)) > > + { > > + rtx cst = const0_rtx; > > + rtx tmp = gen_rtx_SUBREG (V2DImode, gen_reg_rtx (DImode), 0); > > + > > + /* Prefer all ones vector in case of -1. */ > > + if (constm1_operand (*op, GET_MODE (*op))) > > + cst = *op; > > + cst = gen_rtx_CONST_VECTOR (V2DImode, gen_rtvec (2, *op, cst)); > > It took me a while to decipher the above functionality ;) > > Why not just: > > else if (CONST_INT_P (*op)) > { > rtx tmp = gen_rtx_SUBREG (V2DImode, gen_reg_rtx (DImode), 0); > rtx vec; > > /* Prefer all ones vector in case of -1. */ > if (constm1_operand (*op, GET_MODE (*op))) > vec = CONSTM1_RTX (V2DImode); > else > vec = gen_rtx_CONST_VECTOR (V2DImode, > gen_rtvec (2, *op, const0_rtx)); > > if (!standard_sse_constant_p (vec, V2DImode)) > vec = validize_mem (force_const_mem (V2DImode, vec)); > > emit_insn_before (gen_move_insn (tmp, vec), insn); > *op = tmp; > } Agree. This is more readable. > > Comparing this part to timode_scalar_chain::convert_insn, there is a > NONDEBUG_INSN_P check. Do you need one in the above code? Also, TImode > pass handles REG_EQUAL and REG_EQUIV notes. Does dimode pass also need > this functionality? timode_scalar_chain conversion code is just simpler because of restricted external dependencies for a chain and everything is processed in convert_insn. For dimode_scalar_chain NONDEBUG_INSN_P is checked in convert_reg code. Also I don't think I need anything to do with notes because I don't make PUT_MODE for register. Register mode and register value are unchanged and therefore both debug insns and notes may be skipped. > > Uros. Here is an updated version. Bootstrap and regression testing is in progress. OK for trunk if testing pass? Thanks, Ilya --- gcc/ 2016-05-05 Ilya Enkovich * config/i386/i386.c (dimode_scalar_to_vector_candidate_p): Allow integer constants. (dimode_scalar_chain::vector_const_cost): New. (dimode_scalar_chain::compute_convert_gain): Handle constants. (dimode_scalar_chain::convert_op): Likewise. (dimode_scalar_chain::convert_insn): Likewise. gcc/testsuite/ 2016-05-05 Ilya Enkovich * gcc.target/i386/pr70799-1.c: New test. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 9680aaf..020eb29 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -2789,7 +2789,8 @@ dimode_scalar_to_vector_candidate_p (rtx_insn *insn) return convertible_comparison_p (insn); /* We are interested in DImode promotion only. */ - if (GET_MODE (src) != DImode + if ((GET_MODE (src) != DImode + && !CONST_INT_P (src)) || GET_MODE (dst) != DImode) return false; @@ -2809,24 +2810,31 @@ dimode_scalar_to_vector_candidate_p (rtx_insn *insn) return true; case MEM: + case CONST_INT: return REG_P (dst); default: return false; } - if (!REG_P (XEXP (src, 0)) && !MEM_P (XEXP (src, 0)) + if (!REG_P (XEXP (src, 0)) + && !MEM_P (XEXP (src, 0)) + && !CONST_INT_P (XEXP (src, 0)) /* Check for andnot case. */ && (GET_CODE (src) != AND || GET_CODE (XEXP (src, 0)) != NOT || !REG_P (XEXP (XEXP (src, 0), 0)))) return false; - if (!REG_P (XEXP (src, 1)) && !MEM_P (XEXP (src, 1))) + if (!REG_P (XEXP (src, 1)) + && !MEM_P (XEXP (src, 1)) + && !CONST_INT_P (XEXP (src, 1))) return false; - if (GET_MODE (XEXP (src, 0)) != DImode - || GET_MODE (XEXP (src, 1)) != DImode) + if ((GET_MODE (XEXP (src, 0)) != DImode + && !CONST_INT_P (XEXP (src, 0))) + || (GET_MODE (XEXP (src, 1)) != DImode + && !CONST_INT_P (XEXP (src, 1)))) return false; return true; @@ -3120,6 +3128,7 @@ class dimode_scalar_chain : public scalar_chain void convert_reg (unsigned regno); void make_vector_copies (unsigned regno); void convert_registers (); + int vector_const_cost (rtx exp); }; class timode_scalar_chain : public scalar_chain @@ -3328,6 +3337,19 @@ scalar_chain::build (bitmap candidates, unsigned insn_uid) BITMAP_FREE (queue); } +/* Return a cost of building a vector costant + instead of using a scalar one. */ + +int +dimode_scalar_chain::vector_const_cost (rtx exp) +{ + gcc_assert (CONST_INT_P (exp)); + + if (standard_sse_constant_p (exp, V2DImode)) + return COSTS_N_INSNS (1); + return ix86_cost->sse_load[1]; +} + /* Compute a gain for chain conversion. */ int @@ -3359,11 +3381,25 @@ dimode_scalar_chain::compute_convert_gain () || GET_CODE (src) == IOR || GET_CODE (src) == XOR || GET_CODE (src) == AND) - gain += ix86_cost->add; + { + gain += ix86_cost->add; + if (CONST_INT_P (XEXP (src, 0))) + gain -= vector_const_cost (XEXP (src, 0)); + if (CONST_INT_P (XEXP (src, 1))) + gain -= vector_const_cost (XEXP (src, 1)); + } else if (GET_CODE (src) == COMPARE) { /* Assume comparison cost is the same. */ } + else if (GET_CODE (src) == CONST_INT) + { + if (REG_P (dst)) + gain += COSTS_N_INSNS (2); + else if (MEM_P (dst)) + gain += 2 * ix86_cost->int_store[2] - ix86_cost->sse_store[1]; + gain -= vector_const_cost (src); + } else gcc_unreachable (); } @@ -3639,6 +3675,24 @@ dimode_scalar_chain::convert_op (rtx *op, rtx_insn *insn) } *op = gen_rtx_SUBREG (V2DImode, *op, 0); } + else if (CONST_INT_P (*op)) + { + rtx vec_cst; + rtx tmp = gen_rtx_SUBREG (V2DImode, gen_reg_rtx (DImode), 0); + + /* Prefer all ones vector in case of -1. */ + if (constm1_operand (*op, GET_MODE (*op))) + vec_cst = CONSTM1_RTX (V2DImode); + else + vec_cst = gen_rtx_CONST_VECTOR (V2DImode, + gen_rtvec (2, *op, const0_rtx)); + + if (!standard_sse_constant_p (vec_cst, V2DImode)) + vec_cst = validize_mem (force_const_mem (V2DImode, vec_cst)); + + emit_insn_before (gen_move_insn (tmp, vec_cst), insn); + *op = tmp; + } else { gcc_assert (SUBREG_P (*op)); @@ -3711,6 +3765,10 @@ dimode_scalar_chain::convert_insn (rtx_insn *insn) UNSPEC_PTEST); break; + case CONST_INT: + convert_op (&src, insn); + break; + default: gcc_unreachable (); } diff --git a/gcc/testsuite/gcc.target/i386/pr70799-1.c b/gcc/testsuite/gcc.target/i386/pr70799-1.c new file mode 100644 index 0000000..0abbfb9 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr70799-1.c @@ -0,0 +1,41 @@ +/* PR target/pr70799 */ +/* { dg-do compile { target { ia32 } } } */ +/* { dg-options "-O2 -march=slm" } */ +/* { dg-final { scan-assembler "pxor" } } */ +/* { dg-final { scan-assembler "pcmpeqd" } } */ +/* { dg-final { scan-assembler "movdqa\[ \\t\]+.LC0" } } */ + +long long a, b, c; + +void test1 (void) +{ + long long t; + if (a) + t = 0LL; + else + t = b; + a = c & t; + b = c | t; +} + +void test2 (void) +{ + long long t; + if (a) + t = -1LL; + else + t = b; + a = c & t; + b = c | t; +} + +void test3 (void) +{ + long long t; + if (a) + t = 0xf0f0f0f0f0f0f0f0LL; + else + t = b; + a = c & t; + b = c | t; +}