* 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
* Re: Optimize combination of comparisons to dec+compare
2020-12-10 0:51 Optimize combination of comparisons to dec+compare 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
* RE: Optimize combination of comparisons to dec+compare
2020-12-15 22:05 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-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
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-10 0:51 Optimize combination of comparisons to dec+compare Eugene Rozenfeld
2020-12-10 8:21 ` Richard Biener
2020-12-15 22:05 Eugene Rozenfeld
2020-12-22 23:01 ` Eugene Rozenfeld
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).