From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from server.nextmovesoftware.com (server.nextmovesoftware.com [162.254.253.69]) by sourceware.org (Postfix) with ESMTPS id 8FF3D3853804 for ; Mon, 30 May 2022 12:23:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8FF3D3853804 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=nextmovesoftware.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=nextmovesoftware.com DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nextmovesoftware.com; s=default; h=Content-Type:MIME-Version:Message-ID: Date:Subject:To:From:Sender:Reply-To:Cc:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=G8im+zV6rdY5K4THYZg15DImnUWhykBgqRGyY7+uIJ4=; b=Hw/G4sU+3HT962lS/lne9Ql+cH dmUyMRLxVFH4H2l+Xuf8HNhRMACqYBuOTgTX2Y1/bTgfX79ElCAeQE9cqAdfyINDlHlTTdxq8thsw mD3OpRL3QwQIra+O9kkSlFErtxn3FIpv/vjRLlwMiWRh9eJQcMxbdB6ktz3qrXBTD9kewQceRm5ko ZXe86bvp7/TafEz6oHsNaR8knMp59/2AHSfgMPmJu4KENocloIkzgdcqQRFYRuPSFE1eGCIiY6wy9 YgJlKterCdbkaZbDW5oAD5C0kxq+mLYxu6gByeLiW/vLNtO1EY//AH6+fJ/RaTUt1aR36zvi8p7Cc aZzQnlAA==; Received: from host109-154-46-241.range109-154.btcentralplus.com ([109.154.46.241]:58102 helo=Dell) by server.nextmovesoftware.com with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1nveR4-0000y0-R1 for gcc-patches@gcc.gnu.org; Mon, 30 May 2022 08:23:51 -0400 From: "Roger Sayle" To: "'GCC Patches'" Subject: [PATCH] Fold truncations of left shifts in match.pd Date: Mon, 30 May 2022 13:23:49 +0100 Message-ID: <020201d87420$1e944a80$5bbcdf80$@nextmovesoftware.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0203_01D87428.805B2380" X-Mailer: Microsoft Outlook 16.0 Thread-Index: Adh0Hn9EPJNJNSe7RCiuKjA+E2JOGA== Content-Language: en-gb X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - server.nextmovesoftware.com X-AntiAbuse: Original Domain - gcc.gnu.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - nextmovesoftware.com X-Get-Message-Sender-Via: server.nextmovesoftware.com: authenticated_id: roger@nextmovesoftware.com X-Authenticated-Sender: server.nextmovesoftware.com: roger@nextmovesoftware.com X-Source: X-Source-Args: X-Source-Dir: X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 30 May 2022 12:23:54 -0000 This is a multipart message in MIME format. ------=_NextPart_000_0203_01D87428.805B2380 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Whilst investigating PR 55278, I noticed that the tree-ssa optimizers aren't eliminating the promotions of shifts to "int" as inserted by the c-family front-ends, instead leaving this simplification to be left to the RTL optimizers. This patch allows match.pd to do this itself earlier, narrowing (T)(X << C) to (T)X << C when the constant C is known to be valid for the (narrower) type T. Hence for this simple test case: short foo(short x) { return x << 5; } the .optimized dump currently looks like: short int foo (short int x) { int _1; int _2; short int _4; [local count: 1073741824]: _1 = (int) x_3(D); _2 = _1 << 5; _4 = (short int) _2; return _4; } but with this patch, now becomes: short int foo (short int x) { short int _2; [local count: 1073741824]: _2 = x_1(D) << 5; return _2; } This is always reasonable as RTL expansion knows how to use widening optabs if it makes sense at the RTL level to perform this shift in a wider mode. Of course, there's often a catch. The above simplification not only reduces the number of statements in gimple, but also allows further optimizations, for example including the perception of rotate idioms and bswap16. Alas, optimizing things earlier than anticipated requires several testsuite changes [though all these tests have been confirmed to generate identical assembly code on x86_64]. The only significant change is that the vectorization pass previously wouldn't vectorize rotations if the backend doesn't explicitly provide an optab for them. This is curious as if the rotate is expressed as ior(lshift,rshift) it will vectorize, and likewise RTL expansion will generate the iorv(lshiftv,rshiftv) sequence if required for a vector mode rotation. Hence this patch includes a tweak to the optabs test in tree-vect-stmts.cc's vectorizable_shifts to better reflect the functionality supported by RTL expansion. This patch has been tested on x86_64-pc-linux-gnu with make bootstrap and make -k check, both with and without --target_board=unix{-m32}, with no new failures. Ok for mainline? 2022-05-30 Roger Sayle gcc/ChangeLog * match.pd (convert (lshift @1 INTEGER_CST@2)): Narrow integer left shifts by a constant when the result is truncated, and the shift constant is well-defined for the narrower mode. * tree-vect-stmts.cc (vectorizable_shift): Rotations by constants are vectorizable, if the backend supports logical shifts and IOR logical operations in the required vector mode. gcc/testsuite/ChangeLog * gcc.dg/fold-convlshift-4.c: New test case. * gcc.dg/optimize-bswaphi-1.c: Update found bswap count. * gcc.dg/tree-ssa/pr61839_3.c: Shift is now optimized before VRP. * gcc.dg/vect/vect-over-widen-1-big-array.c: Remove obsolete tests. * gcc.dg/vect/vect-over-widen-1.c: Likewise. * gcc.dg/vect/vect-over-widen-3-big-array.c: Likewise. * gcc.dg/vect/vect-over-widen-3.c: Likewise. * gcc.dg/vect/vect-over-widen-4-big-array.c: Likewise. * gcc.dg/vect/vect-over-widen-4.c: Likewise. Thanks in advance, Roger -- ------=_NextPart_000_0203_01D87428.805B2380 Content-Type: text/plain; name="patchls3b.txt" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="patchls3b.txt" diff --git a/gcc/match.pd b/gcc/match.pd=0A= index c2fed9b..05b34d6 100644=0A= --- a/gcc/match.pd=0A= +++ b/gcc/match.pd=0A= @@ -3637,6 +3637,16 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)=0A= && !integer_zerop (@3))=0A= (lshift (convert @2) @3)))=0A= =0A= +/* Narrow a lshift by constant. */=0A= +(simplify=0A= + (convert (lshift:s@0 @1 INTEGER_CST@2))=0A= + (if (INTEGRAL_TYPE_P (type)=0A= + && INTEGRAL_TYPE_P (TREE_TYPE (@0))=0A= + && TYPE_PRECISION (type) <=3D TYPE_PRECISION (TREE_TYPE (@0))=0A= + && !integer_zerop (@2)=0A= + && wi::ltu_p (wi::to_wide (@2), TYPE_PRECISION (type)))=0A= + (lshift (convert @1) (convert @2))))=0A= +=0A= /* Simplifications of conversions. */=0A= =0A= /* Basic strip-useless-type-conversions / strip_nops. */=0A= diff --git a/gcc/testsuite/gcc.dg/fold-convlshift-4.c = b/gcc/testsuite/gcc.dg/fold-convlshift-4.c=0A= new file mode 100644=0A= index 0000000..001627f=0A= --- /dev/null=0A= +++ b/gcc/testsuite/gcc.dg/fold-convlshift-4.c=0A= @@ -0,0 +1,9 @@=0A= +/* { dg-do compile } */=0A= +/* { dg-options "-O2 -fdump-tree-optimized" } */=0A= +short foo(short x)=0A= +{=0A= + return x << 5;=0A= +}=0A= +=0A= +/* { dg-final { scan-tree-dump-not "\\(int\\)" "optimized" } } */=0A= +/* { dg-final { scan-tree-dump-not "\\(short int\\)" "optimized" } } */=0A= diff --git a/gcc/testsuite/gcc.dg/optimize-bswaphi-1.c = b/gcc/testsuite/gcc.dg/optimize-bswaphi-1.c=0A= index d045da9..a5d8bfd 100644=0A= --- a/gcc/testsuite/gcc.dg/optimize-bswaphi-1.c=0A= +++ b/gcc/testsuite/gcc.dg/optimize-bswaphi-1.c=0A= @@ -68,4 +68,4 @@ get_unaligned_16_be (unsigned char *p)=0A= =0A= =0A= /* { dg-final { scan-tree-dump-times "16 bit load in target endianness = found at" 4 "bswap" } } */=0A= -/* { dg-final { scan-tree-dump-times "16 bit bswap implementation found = at" 5 "bswap" } } */=0A= +/* { dg-final { scan-tree-dump-times "16 bit bswap implementation found = at" 4 "bswap" } } */=0A= diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr61839_3.c = b/gcc/testsuite/gcc.dg/tree-ssa/pr61839_3.c=0A= index bc2126f..38cf792 100644=0A= --- a/gcc/testsuite/gcc.dg/tree-ssa/pr61839_3.c=0A= +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr61839_3.c=0A= @@ -1,6 +1,6 @@=0A= /* PR tree-optimization/61839. */=0A= /* { dg-do run } */=0A= -/* { dg-options "-O2 -fdump-tree-vrp -fdump-tree-optimized = -fdisable-tree-ethread -fdisable-tree-threadfull1" } */=0A= +/* { dg-options "-O2 -fdump-tree-optimized -fdisable-tree-ethread = -fdisable-tree-threadfull1" } */=0A= =0A= __attribute__ ((noinline))=0A= int foo (int a, unsigned b)=0A= @@ -21,6 +21,4 @@ int main ()=0A= foo (-1, b);=0A= }=0A= =0A= -/* Scan for c [12, 13] << 8 in function foo. */=0A= -/* { dg-final { scan-tree-dump-times "3072 : 3328" 1 "vrp1" } } */=0A= /* { dg-final { scan-tree-dump-times "3072" 0 "optimized" } } */=0A= diff --git a/gcc/testsuite/gcc.dg/vect/vect-over-widen-1-big-array.c = b/gcc/testsuite/gcc.dg/vect/vect-over-widen-1-big-array.c=0A= index 9e5f464..9a5141ee 100644=0A= --- a/gcc/testsuite/gcc.dg/vect/vect-over-widen-1-big-array.c=0A= +++ b/gcc/testsuite/gcc.dg/vect/vect-over-widen-1-big-array.c=0A= @@ -58,9 +58,7 @@ int main (void)=0A= }=0A= =0A= /* { dg-final { scan-tree-dump-times "vect_recog_widen_shift_pattern: = detected" 2 "vect" { target vect_widen_shift } } } */=0A= -/* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: = detected:[^\n]* << 3} "vect" } } */=0A= /* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: = detected:[^\n]* >> 3} "vect" } } */=0A= -/* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: = detected:[^\n]* << 8} "vect" } } */=0A= /* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: = detected:[^\n]* >> 5} "vect" } } */=0A= /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } = */=0A= =0A= diff --git a/gcc/testsuite/gcc.dg/vect/vect-over-widen-1.c = b/gcc/testsuite/gcc.dg/vect/vect-over-widen-1.c=0A= index c2d0797..f2d284c 100644=0A= --- a/gcc/testsuite/gcc.dg/vect/vect-over-widen-1.c=0A= +++ b/gcc/testsuite/gcc.dg/vect/vect-over-widen-1.c=0A= @@ -62,9 +62,7 @@ int main (void)=0A= }=0A= =0A= /* { dg-final { scan-tree-dump-times "vect_recog_widen_shift_pattern: = detected" 2 "vect" { target vect_widen_shift } } } */=0A= -/* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: = detected:[^\n]* << 3} "vect" } } */=0A= /* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: = detected:[^\n]* >> 3} "vect" } } */=0A= -/* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: = detected:[^\n]* << 8} "vect" } } */=0A= /* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: = detected:[^\n]* >> 5} "vect" } } */=0A= /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } = */=0A= =0A= diff --git a/gcc/testsuite/gcc.dg/vect/vect-over-widen-3-big-array.c = b/gcc/testsuite/gcc.dg/vect/vect-over-widen-3-big-array.c=0A= index 37da7c9..6f89aac 100644=0A= --- a/gcc/testsuite/gcc.dg/vect/vect-over-widen-3-big-array.c=0A= +++ b/gcc/testsuite/gcc.dg/vect/vect-over-widen-3-big-array.c=0A= @@ -59,9 +59,7 @@ int main (void)=0A= return 0;=0A= }=0A= =0A= -/* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: = detected:[^\n]* << 3} "vect" } } */=0A= /* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: = detected:[^\n]* >> 3} "vect" } } */=0A= /* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: = detected:[^\n]* >> 8} "vect" } } */=0A= -/* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: = detected:[^\n]* << 9} "vect" } } */=0A= /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } = */=0A= =0A= diff --git a/gcc/testsuite/gcc.dg/vect/vect-over-widen-3.c = b/gcc/testsuite/gcc.dg/vect/vect-over-widen-3.c=0A= index 4138480..a1e1182 100644=0A= --- a/gcc/testsuite/gcc.dg/vect/vect-over-widen-3.c=0A= +++ b/gcc/testsuite/gcc.dg/vect/vect-over-widen-3.c=0A= @@ -57,9 +57,7 @@ int main (void)=0A= return 0;=0A= }=0A= =0A= -/* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: = detected:[^\n]* << 3} "vect" } } */=0A= /* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: = detected:[^\n]* >> 3} "vect" } } */=0A= /* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: = detected:[^\n]* >> 8} "vect" } } */=0A= -/* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: = detected:[^\n]* << 9} "vect" } } */=0A= /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } = */=0A= =0A= diff --git a/gcc/testsuite/gcc.dg/vect/vect-over-widen-4-big-array.c = b/gcc/testsuite/gcc.dg/vect/vect-over-widen-4-big-array.c=0A= index 514337c..03a6e67 100644=0A= --- a/gcc/testsuite/gcc.dg/vect/vect-over-widen-4-big-array.c=0A= +++ b/gcc/testsuite/gcc.dg/vect/vect-over-widen-4-big-array.c=0A= @@ -62,9 +62,7 @@ int main (void)=0A= }=0A= =0A= /* { dg-final { scan-tree-dump-times "vect_recog_widen_shift_pattern: = detected" 2 "vect" { target vect_widen_shift } } } */=0A= -/* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: = detected:[^\n]* << 3} "vect" } } */=0A= /* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: = detected:[^\n]* >> 3} "vect" } } */=0A= -/* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: = detected:[^\n]* << 8} "vect" } } */=0A= /* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: = detected:[^\n]* >> 5} "vect" } } */=0A= /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } = */=0A= =0A= diff --git a/gcc/testsuite/gcc.dg/vect/vect-over-widen-4.c = b/gcc/testsuite/gcc.dg/vect/vect-over-widen-4.c=0A= index 3d536d5..0ef377f 100644=0A= --- a/gcc/testsuite/gcc.dg/vect/vect-over-widen-4.c=0A= +++ b/gcc/testsuite/gcc.dg/vect/vect-over-widen-4.c=0A= @@ -66,9 +66,7 @@ int main (void)=0A= }=0A= =0A= /* { dg-final { scan-tree-dump-times "vect_recog_widen_shift_pattern: = detected" 2 "vect" { target vect_widen_shift } } } */=0A= -/* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: = detected:[^\n]* << 3} "vect" } } */=0A= /* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: = detected:[^\n]* >> 3} "vect" } } */=0A= -/* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: = detected:[^\n]* << 8} "vect" } } */=0A= /* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: = detected:[^\n]* >> 5} "vect" } } */=0A= /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } = */=0A= =0A= diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc=0A= index 8327e9d..3c54f04 100644=0A= --- a/gcc/tree-vect-stmts.cc=0A= +++ b/gcc/tree-vect-stmts.cc=0A= @@ -5841,6 +5841,14 @@ vectorizable_shift (vec_info *vinfo,=0A= }=0A= vec_mode =3D TYPE_MODE (vectype);=0A= icode =3D (int) optab_handler (optab, vec_mode);=0A= +=0A= + /* RTL expansion knows how to expand rotates using shift/or. */=0A= + if (icode =3D=3D CODE_FOR_nothing=0A= + && (code =3D=3D LROTATE_EXPR || code =3D=3D RROTATE_EXPR)=0A= + && optab_handler (ior_optab, vec_mode) !=3D CODE_FOR_nothing=0A= + && optab_handler (ashl_optab, vec_mode) !=3D CODE_FOR_nothing)=0A= + icode =3D (int) optab_handler (lshr_optab, vec_mode);=0A= +=0A= if (icode =3D=3D CODE_FOR_nothing)=0A= {=0A= if (dump_enabled_p ())=0A= ------=_NextPart_000_0203_01D87428.805B2380--