public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: Optimize combination of comparisons to dec+compare
@ 2020-12-15 22:05 Eugene Rozenfeld
  2020-12-22 23:01 ` Eugene Rozenfeld
  0 siblings, 1 reply; 4+ messages in thread
From: Eugene Rozenfeld @ 2020-12-15 22:05 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

Richard,

> Do we already handle x < y || x <= CST to x <= y - CST?

That is an invalid transformation: e.g., consider x=3, y=4, CST=2.
Can you please clarify?

Thanks,

Eugene

-----Original Message-----
From: Richard Biener <richard.guenther@gmail.com> 
Sent: Thursday, December 10, 2020 12:21 AM
To: Eugene Rozenfeld <Eugene.Rozenfeld@microsoft.com>
Cc: gcc-patches@gcc.gnu.org
Subject: Re: Optimize combination of comparisons to dec+compare

On Thu, Dec 10, 2020 at 1:52 AM Eugene Rozenfeld via Gcc-patches <gcc-patches@gcc.gnu.org> wrote:
>
> This patch adds a pattern for optimizing x < y || x == XXX_MIN to x <= 
> y-1 if y is an integer with TYPE_OVERFLOW_WRAPS.

Do we already handle x < y || x <= CST to x <= y - CST?
That is, the XXX_MIN case is just a special-case of generic anti-range testing?  For anti-range testing with signed types we pun to unsigned when possible.

> This fixes pr96674.
>
> Tested on x86_64-pc-linux-gnu.
>
> For this function
>
> bool f(unsigned a, unsigned b)
> {
>     return (b == 0) | (a < b);
> }
>
> the code without the patch is
>
> test   esi,esi
> sete   al
> cmp    esi,edi
> seta   dl
> or     eax,edx
> ret
>
> the code with the patch is
>
> sub    esi,0x1
> cmp    esi,edi
> setae  al
> ret
>
> Eugene
>
> gcc/
> PR tree-optimization/96674
> * match.pd: New pattern x < y || x == XXX_MIN --> x <= y - 1
>
> gcc/testsuite
> * gcc.dg/pr96674.c: New test.
>

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

* RE: Optimize combination of comparisons to dec+compare
  2020-12-15 22:05 Optimize combination of comparisons to dec+compare Eugene Rozenfeld
@ 2020-12-22 23:01 ` Eugene Rozenfeld
  0 siblings, 0 replies; 4+ messages in thread
From: Eugene Rozenfeld @ 2020-12-22 23:01 UTC (permalink / raw)
  To: Richard Biener, gcc-patches

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

Re-sending my question and re-attaching the patch.

Richard, can you please clarify your feedback?

Thanks,

Eugene

-----Original Message-----
From: Gcc-patches <gcc-patches-bounces@gcc.gnu.org> On Behalf Of Eugene Rozenfeld via Gcc-patches
Sent: Tuesday, December 15, 2020 2:06 PM
To: Richard Biener <richard.guenther@gmail.com>
Cc: gcc-patches@gcc.gnu.org
Subject: [EXTERNAL] Re: Optimize combination of comparisons to dec+compare

Richard,

> Do we already handle x < y || x <= CST to x <= y - CST?

That is an invalid transformation: e.g., consider x=3, y=4, CST=2.
Can you please clarify?

Thanks,

Eugene

-----Original Message-----
From: Richard Biener <richard.guenther@gmail.com> 
Sent: Thursday, December 10, 2020 12:21 AM
To: Eugene Rozenfeld <Eugene.Rozenfeld@microsoft.com>
Cc: gcc-patches@gcc.gnu.org
Subject: Re: Optimize combination of comparisons to dec+compare

On Thu, Dec 10, 2020 at 1:52 AM Eugene Rozenfeld via Gcc-patches <gcc-patches@gcc.gnu.org> wrote:
>
> This patch adds a pattern for optimizing x < y || x == XXX_MIN to x <= 
> y-1 if y is an integer with TYPE_OVERFLOW_WRAPS.

Do we already handle x < y || x <= CST to x <= y - CST?
That is, the XXX_MIN case is just a special-case of generic anti-range testing?  For anti-range testing with signed types we pun to unsigned when possible.

> This fixes pr96674.
>
> Tested on x86_64-pc-linux-gnu.
>
> For this function
>
> bool f(unsigned a, unsigned b)
> {
>     return (b == 0) | (a < b);
> }
>
> the code without the patch is
>
> test   esi,esi
> sete   al
> cmp    esi,edi
> seta   dl
> or     eax,edx
> ret
>
> the code with the patch is
>
> sub    esi,0x1
> cmp    esi,edi
> setae  al
> ret
>
> Eugene
>
> gcc/
> PR tree-optimization/96674
> * match.pd: New pattern x < y || x == XXX_MIN --> x <= y - 1
>
> gcc/testsuite
> * gcc.dg/pr96674.c: New test.
>

[-- Attachment #2: 0001-Optimize-combination-of-comparisons-to-dec-compare.patch --]
[-- Type: application/octet-stream, Size: 2504 bytes --]

From 39215c58f5f640920d81cbe43503342c8b518cd9 Mon Sep 17 00:00:00 2001
From: Eugene Rozenfeld <erozen@microsoft.com>
Date: Wed, 9 Dec 2020 16:44:25 -0800
Subject: [PATCH] Optimize combination of comparisons to dec+compare

This patch adds a pattern for optimizing
x < y || x == XXX_MIN to x <= y-1
if y is an integer with TYPE_OVERFLOW_WRAPS.

This fixes pr96674.

Tested on x86_64-pc-linux-gnu.

For this function

bool f(unsigned a, unsigned b)
{
    return (b == 0) | (a < b);
}

the code without the patch is

test   esi,esi
sete   al
cmp    esi,edi
seta   dl
or     eax,edx
ret

the code with the patch is

sub    esi,0x1
cmp    esi,edi
setae  al
ret

gcc/
PR tree-optimization/96674
* match.pd: New pattern x < y || x == XXX_MIN --> x <= y - 1

gcc/testsuite
* gcc.dg/pr96674.c: New test.
---
 gcc/match.pd                   |  7 +++++++
 gcc/testsuite/gcc.dg/pr96674.c | 28 ++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/pr96674.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 68201ff2e07..c29af540152 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -2084,6 +2084,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
     (if (eqne == NE_EXPR)
      { constant_boolean_node (true, type); }))))
 
+/* x < y || x == XXX_MIN --> x <= y - 1 */
+(simplify
+ (bit_ior (eq @1 min_value) (lt @0 @1))
+  (if (INTEGRAL_TYPE_P (TREE_TYPE (@1))
+       && TYPE_OVERFLOW_WRAPS (TREE_TYPE (@1)))
+  (le @0 (minus @1 { build_int_cst (TREE_TYPE (@1), 1); }))))
+
 /* Convert (X == CST1) && (X OP2 CST2) to a known value
    based on CST1 OP2 CST2.  Similarly for (X != CST1).  */
 
diff --git a/gcc/testsuite/gcc.dg/pr96674.c b/gcc/testsuite/gcc.dg/pr96674.c
new file mode 100644
index 00000000000..c7f20bffabb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr96674.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-options "-O -fdump-tree-optimized -fwrapv" } */
+
+#include <limits.h>
+#include <stdbool.h>
+
+bool __attribute__ ((noinline)) test1 (unsigned a, unsigned b)
+{
+    return (b == 0) | (a < b);
+}
+
+bool __attribute__ ((noinline)) test2 (int a, int b)
+{
+    return (b == INT_MIN) | (a < b);
+}
+
+int main()
+{
+    if (!test1 (1, 0) || !test1 (1, 2) || test1 (2, 1) ||
+        !test2 (1, INT_MIN) || !test2 (1, 2) || test2 (2, 1)) {
+        __builtin_abort();	
+    }
+
+    return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "\\+ 4294967295;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\\+ -1;" 1 "optimized" } } */
-- 
2.17.1


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

* Re: Optimize combination of comparisons to dec+compare
  2020-12-10  0:51 Eugene Rozenfeld
@ 2020-12-10  8:21 ` Richard Biener
  0 siblings, 0 replies; 4+ messages in thread
From: Richard Biener @ 2020-12-10  8:21 UTC (permalink / raw)
  To: Eugene Rozenfeld; +Cc: gcc-patches

On Thu, Dec 10, 2020 at 1:52 AM Eugene Rozenfeld via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> This patch adds a pattern for optimizing
> x < y || x == XXX_MIN to x <= y-1
> if y is an integer with TYPE_OVERFLOW_WRAPS.

Do we already handle x < y || x <= CST to x <= y - CST?
That is, the XXX_MIN case is just a special-case of generic
anti-range testing?  For anti-range testing with signed types
we pun to unsigned when possible.

> This fixes pr96674.
>
> Tested on x86_64-pc-linux-gnu.
>
> For this function
>
> bool f(unsigned a, unsigned b)
> {
>     return (b == 0) | (a < b);
> }
>
> the code without the patch is
>
> test   esi,esi
> sete   al
> cmp    esi,edi
> seta   dl
> or     eax,edx
> ret
>
> the code with the patch is
>
> sub    esi,0x1
> cmp    esi,edi
> setae  al
> ret
>
> Eugene
>
> gcc/
> PR tree-optimization/96674
> * match.pd: New pattern x < y || x == XXX_MIN --> x <= y - 1
>
> gcc/testsuite
> * gcc.dg/pr96674.c: New test.
>

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

* Optimize combination of comparisons to dec+compare
@ 2020-12-10  0:51 Eugene Rozenfeld
  2020-12-10  8:21 ` Richard Biener
  0 siblings, 1 reply; 4+ messages in thread
From: Eugene Rozenfeld @ 2020-12-10  0:51 UTC (permalink / raw)
  To: gcc-patches

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

This patch adds a pattern for optimizing 
x < y || x == XXX_MIN to x <= y-1
if y is an integer with TYPE_OVERFLOW_WRAPS.

This fixes pr96674.

Tested on x86_64-pc-linux-gnu.

For this function

bool f(unsigned a, unsigned b)
{
    return (b == 0) | (a < b);
}

the code without the patch is

test   esi,esi
sete   al
cmp    esi,edi
seta   dl
or     eax,edx
ret    

the code with the patch is

sub    esi,0x1
cmp    esi,edi
setae  al
ret    

Eugene

gcc/
PR tree-optimization/96674
* match.pd: New pattern x < y || x == XXX_MIN --> x <= y - 1

gcc/testsuite
* gcc.dg/pr96674.c: New test.


[-- Attachment #2: 0001-Optimize-combination-of-comparisons-to-dec-compare.patch --]
[-- Type: application/octet-stream, Size: 2504 bytes --]

From 39215c58f5f640920d81cbe43503342c8b518cd9 Mon Sep 17 00:00:00 2001
From: Eugene Rozenfeld <erozen@microsoft.com>
Date: Wed, 9 Dec 2020 16:44:25 -0800
Subject: [PATCH] Optimize combination of comparisons to dec+compare

This patch adds a pattern for optimizing
x < y || x == XXX_MIN to x <= y-1
if y is an integer with TYPE_OVERFLOW_WRAPS.

This fixes pr96674.

Tested on x86_64-pc-linux-gnu.

For this function

bool f(unsigned a, unsigned b)
{
    return (b == 0) | (a < b);
}

the code without the patch is

test   esi,esi
sete   al
cmp    esi,edi
seta   dl
or     eax,edx
ret

the code with the patch is

sub    esi,0x1
cmp    esi,edi
setae  al
ret

gcc/
PR tree-optimization/96674
* match.pd: New pattern x < y || x == XXX_MIN --> x <= y - 1

gcc/testsuite
* gcc.dg/pr96674.c: New test.
---
 gcc/match.pd                   |  7 +++++++
 gcc/testsuite/gcc.dg/pr96674.c | 28 ++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/pr96674.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 68201ff2e07..c29af540152 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -2084,6 +2084,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
     (if (eqne == NE_EXPR)
      { constant_boolean_node (true, type); }))))
 
+/* x < y || x == XXX_MIN --> x <= y - 1 */
+(simplify
+ (bit_ior (eq @1 min_value) (lt @0 @1))
+  (if (INTEGRAL_TYPE_P (TREE_TYPE (@1))
+       && TYPE_OVERFLOW_WRAPS (TREE_TYPE (@1)))
+  (le @0 (minus @1 { build_int_cst (TREE_TYPE (@1), 1); }))))
+
 /* Convert (X == CST1) && (X OP2 CST2) to a known value
    based on CST1 OP2 CST2.  Similarly for (X != CST1).  */
 
diff --git a/gcc/testsuite/gcc.dg/pr96674.c b/gcc/testsuite/gcc.dg/pr96674.c
new file mode 100644
index 00000000000..c7f20bffabb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr96674.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-options "-O -fdump-tree-optimized -fwrapv" } */
+
+#include <limits.h>
+#include <stdbool.h>
+
+bool __attribute__ ((noinline)) test1 (unsigned a, unsigned b)
+{
+    return (b == 0) | (a < b);
+}
+
+bool __attribute__ ((noinline)) test2 (int a, int b)
+{
+    return (b == INT_MIN) | (a < b);
+}
+
+int main()
+{
+    if (!test1 (1, 0) || !test1 (1, 2) || test1 (2, 1) ||
+        !test2 (1, INT_MIN) || !test2 (1, 2) || test2 (2, 1)) {
+        __builtin_abort();	
+    }
+
+    return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "\\+ 4294967295;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\\+ -1;" 1 "optimized" } } */
-- 
2.17.1


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

end of thread, other threads:[~2020-12-22 23:01 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-15 22:05 Optimize combination of comparisons to dec+compare Eugene Rozenfeld
2020-12-22 23:01 ` Eugene Rozenfeld
  -- strict thread matches above, loose matches on Subject: below --
2020-12-10  0:51 Eugene Rozenfeld
2020-12-10  8:21 ` Richard Biener

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).