public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Optimize and+or+sub into xor+not (PR94882)
@ 2020-05-29  3:10 Naveen Hurugalawadi
  2020-06-02  9:27 ` Richard Biener
  0 siblings, 1 reply; 9+ messages in thread
From: Naveen Hurugalawadi @ 2020-05-29  3:10 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 480 bytes --]

Hi,

Please find attached the patch that addresses PR94882.

Bootstrapped and regression tested on x86_64-pc-linux-gnu.

Thanks,
Naveen

match.pd: (x & y) - (x | y) - 1 -> ~(x ^ y) simplification [PR94882]

2029-05-04  Naveen H S  <naveenh@marvell.com>

        PR tree-optimization/94882

        * match.pd (x & y) - (x | y) - 1 -> ~(x ^ y): New simplification.

        * gcc.dg/tree-ssa/pr94882.c: New test.
        * gcc.dg/tree-ssa/pr94882-1.c: New test.

[-- Attachment #2: 2.patch --]
[-- Type: application/octet-stream, Size: 2630 bytes --]

diff --git a/gcc/match.pd b/gcc/match.pd
index 33ee1a920bf..00eca4434d0 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -1139,6 +1139,17 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (bit_xor (bit_ior:c (bit_not @0) @1) (bit_ior:c @0 (bit_not @1)))
  (bit_xor @0 @1))
 
+/* ((x & y) - (x | y)) - 1 -> ~(x ^ y) */
+(simplify
+ (minus (bit_and @0 @1) (plus:c (bit_ior @0 @1) integer_onep))
+ (bit_not (bit_xor @0 @1)))
+(simplify
+ (plus (minus (bit_and @0 @1) (bit_ior @0 @1)) integer_all_onesp)
+ (bit_not (bit_xor @0 @1)))
+(simplify
+ (minus (plus (bit_and @0 @1) integer_all_onesp) (bit_ior @0 @1))
+ (bit_not (bit_xor @0 @1)))
+
 /* ~x & ~y -> ~(x | y)
    ~x | ~y -> ~(x & y) */
 (for op (bit_and bit_ior)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94882-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94882-1.c
new file mode 100644
index 00000000000..244a9d1c1e4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94882-1.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-not " x_\[0-9]+\\\(D\\\) & y_\[0-9]+\\\(D\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-not " x_\[0-9]+\\\(D\\\) \\| y_\[0-9]+\\\(D\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-times " x_\[0-9]+\\\(D\\\) \\^ y_\[0-9]+\\\(D\\\);" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " ~_\[0-9]\+" 3 "optimized" } } */
+
+int
+f (int x, int y)
+{
+  int t = x & y;
+  int tt = x | y;
+  t = t - tt;
+  return t + -1;
+}
+
+int
+g (int x, int y)
+{
+  int t = x & y;
+  int tt = x | y;
+  t = t - 1;
+  return t - tt;
+}
+
+int
+h (int x, int y)
+{
+  int t = x & y;
+  int tt = x | y;
+  tt = tt + 1;
+  return t - tt;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94882.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94882.c
new file mode 100644
index 00000000000..ba590d93846
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94882.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-not " x_\[0-9]+\\\(D\\\) & y_\[0-9]+\\\(D\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-not " x_\[0-9]+\\\(D\\\) \\| y_\[0-9]+\\\(D\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-times " x_\[0-9]+\\\(D\\\) \\^ y_\[0-9]+\\\(D\\\);" 4 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " ~_\[0-9]\+" 4 "optimized" } } */
+
+int
+f (int x, int y)
+{
+  return (x & y) - (x | y) - 1;
+}
+
+int i(int x, int y)
+{
+    return (x & y) - 1 - (x | y);
+}
+
+int j(int x, int y)
+{
+    return (x & y) - ((x | y) + 1);
+}
+
+int k(int x, int y)
+{
+    return (x & y) - (1 + (x | y));
+}

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Optimize and+or+sub into xor+not (PR94882)
  2020-05-29  3:10 [PATCH] Optimize and+or+sub into xor+not (PR94882) Naveen Hurugalawadi
@ 2020-06-02  9:27 ` Richard Biener
  2020-06-03 10:36   ` [EXT] " Naveen Hurugalawadi
  0 siblings, 1 reply; 9+ messages in thread
From: Richard Biener @ 2020-06-02  9:27 UTC (permalink / raw)
  To: Naveen Hurugalawadi; +Cc: gcc-patches

On Fri, May 29, 2020 at 5:56 AM Naveen Hurugalawadi via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> Hi,
>
> Please find attached the patch that addresses PR94882.
>
> Bootstrapped and regression tested on x86_64-pc-linux-gnu.

Is the pattern correct for saturating arithmetic?  Some related
patterns test !TYPE_SATURATING.   I guess that the
pattern is still correct for

(unsigned)((x & y) - (x | y)) + -1u

which would be one more variant to test.  That is, the need to
spell out three different cases (do they all appear for signed
integer?) hints at lack of canonicalization (for the fear of
undefined overflow I guess).  Also raises the question
whether the pattern should be guarded with !TYPE_OVERFLOW_SANITIZED
and/or !TYPE_OVERFLOW_TRAPS

+ (minus (bit_and @0 @1) (plus:c (bit_ior @0 @1) integer_onep))

the plus does not required :c (constants are canonicalized last)

+ (bit_not (bit_xor @0 @1)))

can you add some cases with unsigned types and types
smaller than int (thus with integral promotion applied)?

Thanks,
Richard.

> Thanks,
> Naveen
>
> match.pd: (x & y) - (x | y) - 1 -> ~(x ^ y) simplification [PR94882]
>
> 2029-05-04  Naveen H S  <naveenh@marvell.com>
>
>         PR tree-optimization/94882
>
>         * match.pd (x & y) - (x | y) - 1 -> ~(x ^ y): New simplification.
>
>         * gcc.dg/tree-ssa/pr94882.c: New test.
>         * gcc.dg/tree-ssa/pr94882-1.c: New test.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: [EXT] Re: [PATCH] Optimize and+or+sub into xor+not (PR94882)
  2020-06-02  9:27 ` Richard Biener
@ 2020-06-03 10:36   ` Naveen Hurugalawadi
  2020-06-04  8:14     ` Richard Biener
  0 siblings, 1 reply; 9+ messages in thread
From: Naveen Hurugalawadi @ 2020-06-03 10:36 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 449 bytes --]

Hi Richard,

Thanks for reviewing the patch and sharing your comments.

>> pattern should be guarded with !TYPE_OVERFLOW_SANITIZED
>> and/or !TYPE_OVERFLOW_TRAPS
Done.

>> can you add some cases with unsigned types and types
>> smaller than int (thus with integral promotion applied)?
Done.

Please find attached the modified patch as per your suggestions.
Bootstrapped and regression tested on x86_64-pc-linux-gnu.

Thanks,
Naveen

[-- Attachment #2: pr94882.patch --]
[-- Type: application/octet-stream, Size: 7185 bytes --]

diff --git a/gcc/match.pd b/gcc/match.pd
index 33ee1a920bf..0e2e5c14bb3 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -1139,6 +1139,29 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (bit_xor (bit_ior:c (bit_not @0) @1) (bit_ior:c @0 (bit_not @1)))
  (bit_xor @0 @1))
 
+/* ((x & y) - (x | y)) - 1 -> ~(x ^ y) */
+(simplify
+ (plus (nop_convert1? (minus (nop_convert2? (bit_and @0 @1))
+			     (nop_convert3? (bit_ior @0 @1))))
+       (nop_convert4? integer_all_onesp))
+ (if (!TYPE_OVERFLOW_SANITIZED (type) && !TYPE_OVERFLOW_TRAPS (type)
+      && !TYPE_SATURATING (type))
+ (bit_not (convert (bit_xor @0 @1)))))
+(simplify
+ (minus (nop_convert1? (plus (nop_convert2? (bit_and @0 @1))
+			     (nop_convert3? integer_all_onesp)))
+	(nop_convert4? (bit_ior @0 @1)))
+ (if (!TYPE_OVERFLOW_SANITIZED (type) && !TYPE_OVERFLOW_TRAPS (type)
+      && !TYPE_SATURATING (type))
+ (bit_not (convert (bit_xor @0 @1)))))
+(simplify
+ (minus (nop_convert1? (bit_and @0 @1))
+	(nop_convert2? (plus (nop_convert3? (bit_ior @0 @1))
+			     (nop_convert4? integer_onep))))
+ (if (!TYPE_OVERFLOW_SANITIZED (type) && !TYPE_OVERFLOW_TRAPS (type)
+      && !TYPE_SATURATING (type))
+ (bit_not (convert (bit_xor @0 @1)))))
+
 /* ~x & ~y -> ~(x | y)
    ~x | ~y -> ~(x & y) */
 (for op (bit_and bit_ior)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94882-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94882-1.c
new file mode 100644
index 00000000000..976b8e5bbdc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94882-1.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-not "x_\[0-9]+\\\(D\\\) & y_\[0-9]+\\\(D\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "x_\[0-9]+\\\(D\\\) \\| y_\[0-9]+\\\(D\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-times "x_\[0-9]+\\\(D\\\) \\^ y_\[0-9]+\\\(D\\\);" 4 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "~_\[0-9]\+" 4 "optimized" } } */
+
+int
+a (int x, int y)
+{
+  int t = x & y;
+  int tt = x | y;
+  t = t - tt;
+  return t + -1;
+}
+
+int
+b (int x, int y)
+{
+  int t = x & y;
+  int tt = x | y;
+  t = t - 1;
+  return t - tt;
+}
+
+int
+c (int x, int y)
+{
+  int t = x & y;
+  int tt = x | y;
+  tt = tt + 1;
+  return t - tt;
+}
+
+int
+d (int x, int y)
+{
+  int t = x & y;
+  int tt = x | y;
+  tt = tt + 1;
+  return t - tt;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94882-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94882-2.c
new file mode 100644
index 00000000000..7f533b6d468
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94882-2.c
@@ -0,0 +1,78 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-not "x_\[0-9]+\\\(D\\\) & y_\[0-9]+\\\(D\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "x_\[0-9]+\\\(D\\\) \\| y_\[0-9]+\\\(D\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-times "x_\[0-9]+\\\(D\\\) \\^ y_\[0-9]+\\\(D\\\);" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "~_\[0-9]\+" 8 "optimized" } } */
+
+int
+a (int x, int y)
+{
+  unsigned t = x & y;
+  unsigned tt = x | y;
+  t = t - tt;
+  return t + -1;
+}
+
+int
+a1 (int x, int y)
+{
+  int t = x & y;
+  int tt = x | y;
+  unsigned t1 = t - tt;
+  return t1 + -1;
+}
+
+int
+b (int x, int y)
+{
+  unsigned t = x & y;
+  unsigned tt = x | y;
+  t = t - 1;
+  return t - tt;
+}
+
+int
+b1 (int x, int y)
+{
+  int t = x & y;
+  int tt = x | y;
+  unsigned t1 = t - 1;
+  return t1 - tt;
+}
+
+int
+c (int x, int y)
+{
+  unsigned t = x & y;
+  unsigned tt = x | y;
+  tt = tt + 1;
+  return t - tt;
+}
+
+int
+c1 (int x, int y)
+{
+  int t = x & y;
+  int tt = x | y;
+  unsigned tt1 = tt + 1;
+  return t - tt1;
+}
+
+int
+d (int x, int y)
+{
+  unsigned t = x & y;
+  unsigned tt = x | y;
+  tt = tt + 1;
+  return t - tt;
+}
+
+int
+d1 (int x, int y)
+{
+  int t = x & y;
+  int tt = x | y;
+  unsigned tt1 = tt + 1;
+  return t - tt1;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94882-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94882-3.c
new file mode 100644
index 00000000000..979162f6a5a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94882-3.c
@@ -0,0 +1,79 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-not "x_\[0-9]+\\\(D\\\) & y_\[0-9]+\\\(D\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "x_\[0-9]+\\\(D\\\) \\| y_\[0-9]+\\\(D\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-times "x_\[0-9]+\\\(D\\\) \\^ y_\[0-9]+\\\(D\\\);" 4 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "_\[0-9] \\^ _\[0-9]" 4 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "~_\[0-9]\+" 8 "optimized" } } */
+
+signed char
+a (short x, short y)
+{
+  unsigned char t = (unsigned char) (x & y);
+  unsigned char tt = (unsigned char) (x | y);
+  t = t - tt;
+  return (signed char) (t + -1);
+}
+
+unsigned char
+a1 (signed char x, signed char y)
+{
+  short t = (short) (x & y);
+  short tt = (short) (x | y);
+  unsigned char t1 = (unsigned char) (t - tt);
+  return t1 + -1;
+}
+
+signed char
+b (short x, short y)
+{
+  unsigned char t = (unsigned char) (x & y);
+  signed char tt = (signed char) (x | y);
+  t = t - 1;
+  return ((signed char) t - tt);
+}
+
+short
+b1 (short x, short y)
+{
+  int t = (int) (x & y);
+  int tt = (int) (x | y);
+  short t1 = (short) (t - 1);
+  return (short) (t1 - tt);
+}
+
+signed char
+c (unsigned x, unsigned y)
+{
+  unsigned char t = (unsigned char) (x & y);
+  signed char tt = (signed char) (x | y);
+  tt = tt + 1;
+  return (signed char) (t - tt);
+}
+
+unsigned char
+c1 (signed char x, signed char y)
+{
+  unsigned char t = (unsigned char) (x & y);
+  short tt = (short) (x | y);
+  unsigned char tt1 = (unsigned char) (tt + 1);
+  return t - tt1;
+}
+
+signed char
+d (unsigned char x, unsigned char y)
+{
+  int t = (int) (x & y);
+  int tt = (int) (x | y);
+  tt = tt + 1;
+  return (signed char) (t - tt);
+}
+
+unsigned char
+d1 (int x, int y)
+{
+  signed char t = (signed char) (x & y);
+  signed char tt = (signed char) (x | y);
+  unsigned char tt1 = (unsigned char) (tt + 1);
+  return (unsigned char) (t - tt1);
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94882.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94882.c
new file mode 100644
index 00000000000..e7a55308e85
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94882.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-not "x_\[0-9]+\\\(D\\\) & y_\[0-9]+\\\(D\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "x_\[0-9]+\\\(D\\\) \\| y_\[0-9]+\\\(D\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-times "x_\[0-9]+\\\(D\\\) \\^ y_\[0-9]+\\\(D\\\);" 5 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "~_\[0-9]\+" 5 "optimized" } } */
+
+int
+a (int x, int y)
+{
+  return (x & y) - (x | y) - 1;
+}
+
+int
+b (int x, int y)
+{
+  return (x & y) - 1 - (x | y);
+}
+
+int
+c (int x, int y)
+{
+  return (x & y) - ((x | y) + 1);
+}
+
+int
+d (int x, int y)
+{
+  return (x & y) - (1 + (x | y));
+}
+
+int
+e (int x, int y)
+{
+  return (unsigned) ((x & y) - (x | y)) + -1u;
+}

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [EXT] Re: [PATCH] Optimize and+or+sub into xor+not (PR94882)
  2020-06-03 10:36   ` [EXT] " Naveen Hurugalawadi
@ 2020-06-04  8:14     ` Richard Biener
  2020-06-04 12:09       ` Marc Glisse
  2020-06-04 15:09       ` Naveen Hurugalawadi
  0 siblings, 2 replies; 9+ messages in thread
From: Richard Biener @ 2020-06-04  8:14 UTC (permalink / raw)
  To: Naveen Hurugalawadi; +Cc: gcc-patches

On Wed, Jun 3, 2020 at 12:36 PM Naveen Hurugalawadi <naveenh@marvell.com> wrote:
>
> Hi Richard,
>
> Thanks for reviewing the patch and sharing your comments.
>
> >> pattern should be guarded with !TYPE_OVERFLOW_SANITIZED
> >> and/or !TYPE_OVERFLOW_TRAPS
> Done.
>
> >> can you add some cases with unsigned types and types
> >> smaller than int (thus with integral promotion applied)?
> Done.
>
> Please find attached the modified patch as per your suggestions.
> Bootstrapped and regression tested on x86_64-pc-linux-gnu.

+(simplify
+ (plus (nop_convert1? (minus (nop_convert2? (bit_and @0 @1))
+                            (nop_convert3? (bit_ior @0 @1))))
+       (nop_convert4? integer_all_onesp))

nop_convert4 cannot happen, constants will have been constant folded here.
nop_convert2 and nop_convert3 can only happen together since
the bit_and and the bit_ior will have the same type since they share operands.
Btw, one of bit_and or bit_ior needs :c.

+ (if (!TYPE_OVERFLOW_SANITIZED (type) && !TYPE_OVERFLOW_TRAPS (type)
+      && !TYPE_SATURATING (type))

since we now have two types, the type of the plus and the type of the minus
you have to check both of them

So I think it should be

(simplify
 (plus (nop_convert1? (minus@2 (nop_convert2? (bit_and:c @0 @1))
                                                (nop_convert2?
(bit_ior @0 @1))))
         integer_all_onesp)
 (if (!TYPE_OVERFLOW_SANITIZED (type) && !TYPE_OVERFLOW_TRAPS (type)
     && !TYPE_SATURATING (type)
     && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@2))
    && !TYPE_OVERFLOW_TRAPS (TREE_TYPE (@2))
    && !TYPE_SATURATING (TREE_TYPE (@2)))
  (bit_not (convert (bit_xor @0 @1))))))

and the other patterns adjusted accordingly.

Thanks,
Richard.

> Thanks,
> Naveen

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [EXT] Re: [PATCH] Optimize and+or+sub into xor+not (PR94882)
  2020-06-04  8:14     ` Richard Biener
@ 2020-06-04 12:09       ` Marc Glisse
  2020-06-04 12:50         ` Richard Biener
  2020-06-04 15:09       ` Naveen Hurugalawadi
  1 sibling, 1 reply; 9+ messages in thread
From: Marc Glisse @ 2020-06-04 12:09 UTC (permalink / raw)
  To: Richard Biener; +Cc: Naveen Hurugalawadi, gcc-patches

On Thu, 4 Jun 2020, Richard Biener via Gcc-patches wrote:

> (if (!TYPE_OVERFLOW_SANITIZED (type) && !TYPE_OVERFLOW_TRAPS (type)
>     && !TYPE_SATURATING (type)

Would the positive form
TYPE_OVERFLOW_WRAPS (type) || TYPE_OVERFLOW_UNDEFINED (type)
be roughly equivalent and shorter? Or am I missing some cases?

(I didn't look at the patch and if that's the right condition, just 
randomly commenting on this line)

-- 
Marc Glisse

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [EXT] Re: [PATCH] Optimize and+or+sub into xor+not (PR94882)
  2020-06-04 12:09       ` Marc Glisse
@ 2020-06-04 12:50         ` Richard Biener
  0 siblings, 0 replies; 9+ messages in thread
From: Richard Biener @ 2020-06-04 12:50 UTC (permalink / raw)
  To: GCC Patches; +Cc: Naveen Hurugalawadi

On Thu, Jun 4, 2020 at 2:09 PM Marc Glisse <marc.glisse@inria.fr> wrote:
>
> On Thu, 4 Jun 2020, Richard Biener via Gcc-patches wrote:
>
> > (if (!TYPE_OVERFLOW_SANITIZED (type) && !TYPE_OVERFLOW_TRAPS (type)
> >     && !TYPE_SATURATING (type)
>
> Would the positive form
> TYPE_OVERFLOW_WRAPS (type) || TYPE_OVERFLOW_UNDEFINED (type)
> be roughly equivalent and shorter? Or am I missing some cases?

I think TYPE_OVERFLOW_SANITIZED isn't handled here, not sure
if we have saturating integer types (we have FIXED_POINT_TYPE ones).
At least TYPE_OVERFLOW_* do not check TYPE_SATURATING
but only (ANY-)INTEGER_TYPE-ness.

Richard.

> (I didn't look at the patch and if that's the right condition, just
> randomly commenting on this line)
>
> --
> Marc Glisse

^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: [EXT] Re: [PATCH] Optimize and+or+sub into xor+not (PR94882)
  2020-06-04  8:14     ` Richard Biener
  2020-06-04 12:09       ` Marc Glisse
@ 2020-06-04 15:09       ` Naveen Hurugalawadi
  2020-06-15  7:32         ` Richard Biener
  1 sibling, 1 reply; 9+ messages in thread
From: Naveen Hurugalawadi @ 2020-06-04 15:09 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 425 bytes --]

Hi,

Thanks for reviewing the patch and sharing your comments.

>> nop_convert4 cannot happen, constants will have been constant folded here.
Removed.

>> So I think it should be and the other patterns adjusted accordingly.
Modified the remaining patterns accordingly.

Please find attached the modified patch as per your suggestions.
Bootstrapped and regression tested on x86_64-pc-linux-gnu.

Thanks,
Naveen

[-- Attachment #2: pr94882-1.patch --]
[-- Type: application/octet-stream, Size: 7548 bytes --]

diff --git a/gcc/match.pd b/gcc/match.pd
index 33ee1a920bf..eaec42f43e1 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -1139,6 +1139,35 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (bit_xor (bit_ior:c (bit_not @0) @1) (bit_ior:c @0 (bit_not @1)))
  (bit_xor @0 @1))
 
+/* ((x & y) - (x | y)) - 1 -> ~(x ^ y) */
+(simplify
+ (plus (nop_convert1? (minus@2 (nop_convert2? (bit_and:c @0 @1))
+			       (nop_convert2? (bit_ior @0 @1))))
+	integer_all_onesp)
+ (if (!TYPE_OVERFLOW_SANITIZED (type) && !TYPE_OVERFLOW_TRAPS (type)
+      && !TYPE_SATURATING (type) && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@2))
+      && !TYPE_OVERFLOW_TRAPS (TREE_TYPE (@2))
+      && !TYPE_SATURATING (TREE_TYPE (@2)))
+ (bit_not (convert (bit_xor @0 @1)))))
+(simplify
+ (minus (nop_convert1? (plus@2 (nop_convert2? (bit_and:c @0 @1))
+				integer_all_onesp))
+	(nop_convert3? (bit_ior @0 @1)))
+ (if (!TYPE_OVERFLOW_SANITIZED (type) && !TYPE_OVERFLOW_TRAPS (type)
+      && !TYPE_SATURATING (type) && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@2))
+      && !TYPE_OVERFLOW_TRAPS (TREE_TYPE (@2))
+      && !TYPE_SATURATING (TREE_TYPE (@2)))
+ (bit_not (convert (bit_xor @0 @1)))))
+(simplify
+ (minus (nop_convert1? (bit_and @0 @1))
+	(nop_convert2? (plus@2 (nop_convert3? (bit_ior:c @0 @1))
+				integer_onep)))
+ (if (!TYPE_OVERFLOW_SANITIZED (type) && !TYPE_OVERFLOW_TRAPS (type)
+      && !TYPE_SATURATING (type) && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@2))
+      && !TYPE_OVERFLOW_TRAPS (TREE_TYPE (@2))
+      && !TYPE_SATURATING (TREE_TYPE (@2)))
+ (bit_not (convert (bit_xor @0 @1)))))
+
 /* ~x & ~y -> ~(x | y)
    ~x | ~y -> ~(x & y) */
 (for op (bit_and bit_ior)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94882-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94882-1.c
new file mode 100644
index 00000000000..976b8e5bbdc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94882-1.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-not "x_\[0-9]+\\\(D\\\) & y_\[0-9]+\\\(D\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "x_\[0-9]+\\\(D\\\) \\| y_\[0-9]+\\\(D\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-times "x_\[0-9]+\\\(D\\\) \\^ y_\[0-9]+\\\(D\\\);" 4 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "~_\[0-9]\+" 4 "optimized" } } */
+
+int
+a (int x, int y)
+{
+  int t = x & y;
+  int tt = x | y;
+  t = t - tt;
+  return t + -1;
+}
+
+int
+b (int x, int y)
+{
+  int t = x & y;
+  int tt = x | y;
+  t = t - 1;
+  return t - tt;
+}
+
+int
+c (int x, int y)
+{
+  int t = x & y;
+  int tt = x | y;
+  tt = tt + 1;
+  return t - tt;
+}
+
+int
+d (int x, int y)
+{
+  int t = x & y;
+  int tt = x | y;
+  tt = tt + 1;
+  return t - tt;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94882-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94882-2.c
new file mode 100644
index 00000000000..7f533b6d468
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94882-2.c
@@ -0,0 +1,78 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-not "x_\[0-9]+\\\(D\\\) & y_\[0-9]+\\\(D\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "x_\[0-9]+\\\(D\\\) \\| y_\[0-9]+\\\(D\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-times "x_\[0-9]+\\\(D\\\) \\^ y_\[0-9]+\\\(D\\\);" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "~_\[0-9]\+" 8 "optimized" } } */
+
+int
+a (int x, int y)
+{
+  unsigned t = x & y;
+  unsigned tt = x | y;
+  t = t - tt;
+  return t + -1;
+}
+
+int
+a1 (int x, int y)
+{
+  int t = x & y;
+  int tt = x | y;
+  unsigned t1 = t - tt;
+  return t1 + -1;
+}
+
+int
+b (int x, int y)
+{
+  unsigned t = x & y;
+  unsigned tt = x | y;
+  t = t - 1;
+  return t - tt;
+}
+
+int
+b1 (int x, int y)
+{
+  int t = x & y;
+  int tt = x | y;
+  unsigned t1 = t - 1;
+  return t1 - tt;
+}
+
+int
+c (int x, int y)
+{
+  unsigned t = x & y;
+  unsigned tt = x | y;
+  tt = tt + 1;
+  return t - tt;
+}
+
+int
+c1 (int x, int y)
+{
+  int t = x & y;
+  int tt = x | y;
+  unsigned tt1 = tt + 1;
+  return t - tt1;
+}
+
+int
+d (int x, int y)
+{
+  unsigned t = x & y;
+  unsigned tt = x | y;
+  tt = tt + 1;
+  return t - tt;
+}
+
+int
+d1 (int x, int y)
+{
+  int t = x & y;
+  int tt = x | y;
+  unsigned tt1 = tt + 1;
+  return t - tt1;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94882-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94882-3.c
new file mode 100644
index 00000000000..979162f6a5a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94882-3.c
@@ -0,0 +1,79 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-not "x_\[0-9]+\\\(D\\\) & y_\[0-9]+\\\(D\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "x_\[0-9]+\\\(D\\\) \\| y_\[0-9]+\\\(D\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-times "x_\[0-9]+\\\(D\\\) \\^ y_\[0-9]+\\\(D\\\);" 4 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "_\[0-9] \\^ _\[0-9]" 4 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "~_\[0-9]\+" 8 "optimized" } } */
+
+signed char
+a (short x, short y)
+{
+  unsigned char t = (unsigned char) (x & y);
+  unsigned char tt = (unsigned char) (x | y);
+  t = t - tt;
+  return (signed char) (t + -1);
+}
+
+unsigned char
+a1 (signed char x, signed char y)
+{
+  short t = (short) (x & y);
+  short tt = (short) (x | y);
+  unsigned char t1 = (unsigned char) (t - tt);
+  return t1 + -1;
+}
+
+signed char
+b (short x, short y)
+{
+  unsigned char t = (unsigned char) (x & y);
+  signed char tt = (signed char) (x | y);
+  t = t - 1;
+  return ((signed char) t - tt);
+}
+
+short
+b1 (short x, short y)
+{
+  int t = (int) (x & y);
+  int tt = (int) (x | y);
+  short t1 = (short) (t - 1);
+  return (short) (t1 - tt);
+}
+
+signed char
+c (unsigned x, unsigned y)
+{
+  unsigned char t = (unsigned char) (x & y);
+  signed char tt = (signed char) (x | y);
+  tt = tt + 1;
+  return (signed char) (t - tt);
+}
+
+unsigned char
+c1 (signed char x, signed char y)
+{
+  unsigned char t = (unsigned char) (x & y);
+  short tt = (short) (x | y);
+  unsigned char tt1 = (unsigned char) (tt + 1);
+  return t - tt1;
+}
+
+signed char
+d (unsigned char x, unsigned char y)
+{
+  int t = (int) (x & y);
+  int tt = (int) (x | y);
+  tt = tt + 1;
+  return (signed char) (t - tt);
+}
+
+unsigned char
+d1 (int x, int y)
+{
+  signed char t = (signed char) (x & y);
+  signed char tt = (signed char) (x | y);
+  unsigned char tt1 = (unsigned char) (tt + 1);
+  return (unsigned char) (t - tt1);
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94882.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94882.c
new file mode 100644
index 00000000000..e7a55308e85
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94882.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-not "x_\[0-9]+\\\(D\\\) & y_\[0-9]+\\\(D\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "x_\[0-9]+\\\(D\\\) \\| y_\[0-9]+\\\(D\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-times "x_\[0-9]+\\\(D\\\) \\^ y_\[0-9]+\\\(D\\\);" 5 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "~_\[0-9]\+" 5 "optimized" } } */
+
+int
+a (int x, int y)
+{
+  return (x & y) - (x | y) - 1;
+}
+
+int
+b (int x, int y)
+{
+  return (x & y) - 1 - (x | y);
+}
+
+int
+c (int x, int y)
+{
+  return (x & y) - ((x | y) + 1);
+}
+
+int
+d (int x, int y)
+{
+  return (x & y) - (1 + (x | y));
+}
+
+int
+e (int x, int y)
+{
+  return (unsigned) ((x & y) - (x | y)) + -1u;
+}

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [EXT] Re: [PATCH] Optimize and+or+sub into xor+not (PR94882)
  2020-06-04 15:09       ` Naveen Hurugalawadi
@ 2020-06-15  7:32         ` Richard Biener
  2020-07-01 20:50           ` Jeff Law
  0 siblings, 1 reply; 9+ messages in thread
From: Richard Biener @ 2020-06-15  7:32 UTC (permalink / raw)
  To: Naveen Hurugalawadi; +Cc: gcc-patches

On Thu, Jun 4, 2020 at 5:09 PM Naveen Hurugalawadi <naveenh@marvell.com> wrote:
>
> Hi,
>
> Thanks for reviewing the patch and sharing your comments.
>
> >> nop_convert4 cannot happen, constants will have been constant folded here.
> Removed.
>
> >> So I think it should be and the other patterns adjusted accordingly.
> Modified the remaining patterns accordingly.
>
> Please find attached the modified patch as per your suggestions.
> Bootstrapped and regression tested on x86_64-pc-linux-gnu.

OK.

Thanks and sorry for the delay.
Richard.

> Thanks,
> Naveen

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [EXT] Re: [PATCH] Optimize and+or+sub into xor+not (PR94882)
  2020-06-15  7:32         ` Richard Biener
@ 2020-07-01 20:50           ` Jeff Law
  0 siblings, 0 replies; 9+ messages in thread
From: Jeff Law @ 2020-07-01 20:50 UTC (permalink / raw)
  To: Richard Biener, Naveen Hurugalawadi; +Cc: gcc-patches

On Mon, 2020-06-15 at 09:32 +0200, Richard Biener via Gcc-patches wrote:
> On Thu, Jun 4, 2020 at 5:09 PM Naveen Hurugalawadi <naveenh@marvell.com> wrote:
> > Hi,
> > 
> > Thanks for reviewing the patch and sharing your comments.
> > 
> > > > nop_convert4 cannot happen, constants will have been constant folded here.
> > Removed.
> > 
> > > > So I think it should be and the other patterns adjusted accordingly.
> > Modified the remaining patterns accordingly.
> > 
> > Please find attached the modified patch as per your suggestions.
> > Bootstrapped and regression tested on x86_64-pc-linux-gnu.
> 
> OK.
> 
> Thanks and sorry for the delay.
I went ahead and committed the changes to the trunk.

jeff


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-07-01 20:50 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-29  3:10 [PATCH] Optimize and+or+sub into xor+not (PR94882) Naveen Hurugalawadi
2020-06-02  9:27 ` Richard Biener
2020-06-03 10:36   ` [EXT] " Naveen Hurugalawadi
2020-06-04  8:14     ` Richard Biener
2020-06-04 12:09       ` Marc Glisse
2020-06-04 12:50         ` Richard Biener
2020-06-04 15:09       ` Naveen Hurugalawadi
2020-06-15  7:32         ` Richard Biener
2020-07-01 20:50           ` Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).