From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pl1-x62d.google.com (mail-pl1-x62d.google.com [IPv6:2607:f8b0:4864:20::62d]) by sourceware.org (Postfix) with ESMTPS id E3E2F3857027 for ; Tue, 8 Aug 2023 13:19:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E3E2F3857027 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-pl1-x62d.google.com with SMTP id d9443c01a7336-1bc65360648so23480015ad.1 for ; Tue, 08 Aug 2023 06:19:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1691500746; x=1692105546; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=kneoQiZdHgXUE6Dd7g5SMFjiAFvgbySpWzMlzAVnGwE=; b=WYUmac3pobgfz9E9/8q2i5IiFUMgxkb6qReVLzaLIztNP123lQd8mj6VnirdtnbujG RQUlp3ORIYZhfY8wCWOKhImkSNYb5V/Kai01XY8v4zq+AzmvXw0Vn8PX0HgaJgOk6c6m oyJL4L17hadjkzDtc7BrqDhHs6X5Jtonu87GO4edQlQTN2pakaTnHO4XUqktQ43s+Yve AwvuLU6bYYZMOm8HiHJCqEKFtYloli8TarxANlGfKsHmw7EmBXbe0AUyBhUQ7WoOmP4f WP1kvmx49cLJ7pthXENCGS/oDiR/bDm6lAS8zkmDAK2SiFe8Sm/h4ntW9784+WjUy+P7 SpdQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1691500746; x=1692105546; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=kneoQiZdHgXUE6Dd7g5SMFjiAFvgbySpWzMlzAVnGwE=; b=dDjys+15fxWRPQ5qZl6wMr4phl+9L9Dv9+UNrcfXCbkt7Db4xmhEa780atiOmBgWEE /dzaghkGmnrPxDS9+mLUksdPWd59DTtTFwhTVFxmLK+C2uth5nmFlC73gnASfbFP7NN3 jbyrw0H5TQMoSFrtMwe3qKV9/KfPgFPJhR4dfFsX9hc3FHzhmfMW2qel1YukFyhWvFKT 5glIsz6CysF6s/0UCTAkXPAMtk01PMVqzeXALy/so/rlVtlk0Sjc6o5TZj25Tgi8bgYa f564uFG8IfNU15NULIwmr05TuVGPcnHboKBndVgGJnpkHF5R0bnQI07J9kNeyPPJQeKQ 11IA== X-Gm-Message-State: AOJu0YzhOYQ8O8hL5Zih22Is+ElvRLap/+GDL/TqGnwhwraxq/QV6xJB MWBny9kBD5iNwqZu8o7Da7cKQfO2ziAO6Pk4/hI= X-Google-Smtp-Source: AGHT+IG3UNcRKqqhxDntjT4tu0PFlwmc5Oy6FuwuHD4DavJX1UpQ/bLG06sC30vLVWJ22sX50THCetyY7gnvHyit0Jw= X-Received: by 2002:a17:902:a40b:b0:1bc:2d43:c741 with SMTP id p11-20020a170902a40b00b001bc2d43c741mr10583438plq.66.1691500745654; Tue, 08 Aug 2023 06:19:05 -0700 (PDT) MIME-Version: 1.0 References: <20230804214817.1256642-1-drross@redhat.com> In-Reply-To: <20230804214817.1256642-1-drross@redhat.com> From: Richard Biener Date: Tue, 8 Aug 2023 15:18:51 +0200 Message-ID: Subject: Re: [PATCH] match.pd: Implement missed optimization ((x ^ y) & z) | x -> (z & y) | x [PR109938] To: Drew Ross Cc: gcc-patches@gcc.gnu.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On Fri, Aug 4, 2023 at 11:49=E2=80=AFPM Drew Ross via Gcc-patches wrote: > > Adds a simplification for ((x ^ y) & z) | x to be folded into > (z & y) | x. Merges this simplification with ((x | y) & z) | x -> (z & y)= | x > to prevent duplicate pattern. Tested successfully on x86_64 and x86 targe= ts. OK. > + (bit_ior:c (nop_convert1? (bit_and:c (nop_convert2? All these nop_convers makes me think that _maybe_ we could relax type constraints on bitwise operations to allow different signs of operands (and result). Maybe we could simply transparently strip them when matching expressions in the code generated by genmatch? So when we match a bitwise operation the operands get stripped of sign conversions which of course also means that for example (bit_ior (bit_and @0 @1) @0) could have @0 and @1 having different types so on the code generation side we'd either need to manually add (convert ..)s or have genmatch recognize match operand places that can get nop-conversions stripped and apply the convert itself. For (plus (bit_ior @0 @1) @1) and @1 being (nop_convert @2) that might get us not matching up the operands then unless we also adjust that part. So maybe it's not really worth the trouble ... Maybe it would be instead simpler to special case code generation for conditionals that are singleton within an optional group, those could be expanded "inline" (but we'd have to record the number of uses). Richard. > PR tree-opt/109938 > > gcc/ChangeLog: > > * match.pd ((x ^ y) & z) | x -> (z & y) | x: New simplification. > > gcc/testsuite/ChangeLog: > > * gcc.c-torture/execute/pr109938.c: New test. > * gcc.dg/tree-ssa/pr109938.c: New test. > --- > gcc/match.pd | 10 +- > .../gcc.c-torture/execute/pr109938.c | 33 +++++ > gcc/testsuite/gcc.dg/tree-ssa/pr109938.c | 125 ++++++++++++++++++ > 3 files changed, 164 insertions(+), 4 deletions(-) > create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr109938.c > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr109938.c > > diff --git a/gcc/match.pd b/gcc/match.pd > index ee6cef6b09d..884dc622b25 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -1946,10 +1946,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (bitop:c (rbitop:c (bit_not @0) @1) @0) > (bitop @0 @1))) > > -/* ((x | y) & z) | x -> (z & y) | x */ > -(simplify > - (bit_ior:c (bit_and:cs (bit_ior:cs @0 @1) @2) @0) > - (bit_ior (bit_and @2 @1) @0)) > +/* ((x |^ y) & z) | x -> (z & y) | x */ > +(for op (bit_ior bit_xor) > + (simplify > + (bit_ior:c (nop_convert1? (bit_and:c (nop_convert2? (op:c @0 @1)) @2))= @3) > + (if (bitwise_equal_p (@0, @3)) > + (convert (bit_ior (bit_and @1 (convert @2)) (convert @0)))))) > > /* (x | CST1) & CST2 -> (x & CST2) | (CST1 & CST2) */ > (simplify > diff --git a/gcc/testsuite/gcc.c-torture/execute/pr109938.c b/gcc/testsui= te/gcc.c-torture/execute/pr109938.c > new file mode 100644 > index 00000000000..a65d13b305d > --- /dev/null > +++ b/gcc/testsuite/gcc.c-torture/execute/pr109938.c > @@ -0,0 +1,33 @@ > +/* PR tree-opt/109938 */ > + > +#include "../../gcc.dg/tree-ssa/pr109938.c" > + > +int > +main () > +{ > + if (t1 (29789, 29477, 23942) !=3D 30045) __builtin_abort (); > + if (t2 (-20196, 18743, -32901) !=3D -1729) __builtin_abort (); > + if (t3 (2136614690L, 1136698390L, 2123767997L) !=3D 2145003318UL) __bu= iltin_abort (); > + if (t4 (-4878, 9977, 23313) !=3D 61171) __builtin_abort (); > + if (t5 (127, 99, 43) !=3D 127) __builtin_abort (); > + if (t6 (9176690219839792930LL, 3176690219839721234LL, 5671738468274920= 831LL) > + !=3D 9177833729112616754LL) __builtin_abort (); > + if (t7 (29789, 29477, 23942) !=3D 30045) __builtin_abort (); > + if (t8 (23489, 99477, 87942) !=3D 90053) __builtin_abort (); > + if (t9 (10489, 66477, -73313) !=3D 10749) __builtin_abort (); > + if (t10 (2136614690L, -1136614690L, 4136614690UL) !=3D 4284131106UL) > + __builtin_abort (); > + if (t11 (29789, 29477, 12345) !=3D 29821) __builtin_abort (); > + if (t12 (-120, 98, -73) !=3D 170) __builtin_abort (); > + if (t13 (9176690219839792930ULL, -3176690219839721234LL, 5671738468274= 920831ULL) > + !=3D 9221726284835125102ULL) __builtin_abort (); > + v4si a1 =3D {29789, -20196, 23489, 10489}; > + v4si a2 =3D {29477, 18743, 99477, 66477}; > + v4si a3 =3D {23942, -32901, 87942, -73313}; > + v4si r1 =3D {30045, 63807, 90053, 10749}; > + v4si b1 =3D t14 (a1, a2, a3); > + v4si b2 =3D t15 (a1, a2, a3); > + if (__builtin_memcmp (&b1, &r1, sizeof (b1) !=3D 0)) __builtin_abort= (); > + if (__builtin_memcmp (&b2, &r1, sizeof (b2) !=3D 0)) __builtin_abort= (); > + return 0; > +} > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr109938.c b/gcc/testsuite/gcc= .dg/tree-ssa/pr109938.c > new file mode 100644 > index 00000000000..0cae55886c6 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr109938.c > @@ -0,0 +1,125 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-dse1 -Wno-psabi" } */ > + > +typedef int v4si __attribute__((vector_size(4 * sizeof(int)))); > + > +/* Generic */ > +__attribute__((noipa)) int > +t1 (int a, int b, int c) > +{ > + return ((a ^ c) & b) | a; > +} > + > +__attribute__((noipa)) unsigned int > +t2 (int a, unsigned int b, int c) > +{ > + return ((a ^ c) & b) | a; > +} > + > +__attribute__((noipa)) unsigned long > +t3 (unsigned long a, long b, unsigned long c) > +{ > + return ((a ^ c) & b) | a; > +} > + > +__attribute__((noipa)) unsigned short > +t4 (short a, unsigned short b, unsigned short c) > +{ > + return (unsigned short) ((a ^ c) & b) | a; > +} > + > +__attribute__((noipa)) unsigned char > +t5 (unsigned char a, signed char b, signed char c) > +{ > + return ((a ^ c) & b) | a; > +} > + > +__attribute__((noipa)) long long > +t6 (long long a, long long b, long long c) > +{ > + return ((a ^ c) & (unsigned long long) b) | a; > +} > + > +/* Gimple */ > +__attribute__((noipa)) int > +t7 (int a, int b, int c) > +{ > + int t1 =3D a ^ c; > + int t2 =3D t1 & b; > + int t3 =3D t2 | a; > + return t3; > +} > + > +__attribute__((noipa)) int > +t8 (int a, unsigned int b, unsigned int c) > +{ > + unsigned int t1 =3D a ^ c; > + int t2 =3D t1 & b; > + int t3 =3D t2 | a; > + return t3; > +} > + > +__attribute__((noipa)) unsigned int > +t9 (unsigned int a, unsigned int b, int c) > +{ > + unsigned int t1 =3D a ^ c; > + unsigned int t2 =3D t1 & b; > + unsigned int t3 =3D t2 | a; > + return t3; > +} > + > +__attribute__((noipa)) unsigned long > +t10 (unsigned long a, long b, unsigned long c) > +{ > + unsigned long t1 =3D a ^ c; > + unsigned long t2 =3D t1 & b; > + unsigned long t3 =3D t2 | a; > + return t3; > +} > + > +__attribute__((noipa)) unsigned short > +t11 (short a, unsigned short b, short c) > +{ > + short t1 =3D a ^ c; > + unsigned short t2 =3D t1 & b; > + unsigned short t3 =3D t2 | a; > + return t3; > +} > + > +__attribute__((noipa)) unsigned char > +t12 (signed char a, unsigned char b, signed char c) > +{ > + unsigned char t1 =3D a ^ c; > + unsigned char t2 =3D t1 & b; > + unsigned char t3 =3D t2 | a; > + return t3; > +} > + > +__attribute__((noipa)) unsigned long long > +t13 (unsigned long long a, long long b, unsigned long long c) > +{ > + long long t1 =3D a ^ c; > + long long t2 =3D t1 & b; > + unsigned long long t3 =3D t2 | a; > + return t3; > +} > + > +/* Vectors */ > +__attribute__((noipa)) v4si > +t14 (v4si a, v4si b, v4si c) > +{ > + return ((a ^ c) & b) | a; > +} > + > +__attribute__((noipa)) v4si > +t15 (v4si a, v4si b, v4si c) > +{ > + v4si t1 =3D a ^ c; > + v4si t2 =3D t1 & b; > + v4si t3 =3D t2 | a; > + return t3; > +} > + > +/* { dg-final { scan-tree-dump-not " \\\^ " "dse1" } } */ > +/* { dg-final { scan-tree-dump-times " \\\| " 15 "dse1" } } */ > +/* { dg-final { scan-tree-dump-times " & " 15 "dse1" } } */ > -- > 2.39.3 >