diff options
author | Jakub Jelinek <jakub@redhat.com> | 2020-05-04 11:03:32 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2020-05-04 11:03:32 +0200 |
commit | 6b5c7ee0df6b87780f2fd6f2c5759a04e6eed1fe (patch) | |
tree | ad20e71284b9b89bbcf272c547c50ab0d8c754f9 | |
parent | 496f4f884716ae061f771a62e44868a32dbd502f (diff) | |
download | gcc-6b5c7ee0df6b87780f2fd6f2c5759a04e6eed1fe.zip gcc-6b5c7ee0df6b87780f2fd6f2c5759a04e6eed1fe.tar.gz gcc-6b5c7ee0df6b87780f2fd6f2c5759a04e6eed1fe.tar.bz2 |
match.pd: Optimize (x < 0) != (y < 0) into (x ^ y) < 0 [PR94718]
The following patch (on top of the two other PR94718 patches) performs the
actual optimization requested in the PR.
2020-05-04 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/94718
* match.pd ((X < 0) != (Y < 0) into (X ^ Y) < 0): New simplification.
* gcc.dg/tree-ssa/pr94718-4.c: New test.
* gcc.dg/tree-ssa/pr94718-5.c: New test.
-rw-r--r-- | gcc/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/match.pd | 24 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr94718-4.c | 61 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr94718-5.c | 61 |
5 files changed, 153 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 036a403..fae7ece 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,9 @@ 2020-05-04 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/94718 + * match.pd ((X < 0) != (Y < 0) into (X ^ Y) < 0): New simplification. + + PR tree-optimization/94718 * match.pd (bitop (convert @0) (convert? @1)): For GIMPLE, if we can, replace two nop conversions on bit_{and,ior,xor} argument and result with just one conversion on the result or another argument. diff --git a/gcc/match.pd b/gcc/match.pd index 929be14..9c1e239 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -4358,6 +4358,30 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (cmp (bit_and:cs @0 @2) (bit_and:cs @1 @2)) (cmp (bit_and (bit_xor @0 @1) @2) { build_zero_cst (TREE_TYPE (@2)); }))) +/* (X < 0) != (Y < 0) into (X ^ Y) < 0. + (X >= 0) != (Y >= 0) into (X ^ Y) < 0. + (X < 0) == (Y < 0) into (X ^ Y) >= 0. + (X >= 0) == (Y >= 0) into (X ^ Y) >= 0. */ +(for cmp (eq ne) + ncmp (ge lt) + (for sgncmp (ge lt) + (simplify + (cmp (sgncmp @0 integer_zerop@2) (sgncmp @1 integer_zerop)) + (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)) + && !TYPE_UNSIGNED (TREE_TYPE (@0)) + && types_match (@0, @1)) + (ncmp (bit_xor @0 @1) @2))))) +/* (X < 0) == (Y >= 0) into (X ^ Y) < 0. + (X < 0) != (Y >= 0) into (X ^ Y) >= 0. */ +(for cmp (eq ne) + ncmp (lt ge) + (simplify + (cmp:c (lt @0 integer_zerop@2) (ge @1 integer_zerop)) + (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)) + && !TYPE_UNSIGNED (TREE_TYPE (@0)) + && types_match (@0, @1)) + (ncmp (bit_xor @0 @1) @2)))) + /* If we have (A & C) == C where C is a power of 2, convert this into (A & C) != 0. Similarly for NE_EXPR. */ (for cmp (eq ne) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 09979b5..2fedff3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,10 @@ 2020-05-04 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/94718 + * gcc.dg/tree-ssa/pr94718-4.c: New test. + * gcc.dg/tree-ssa/pr94718-5.c: New test. + + PR tree-optimization/94718 * gcc.dg/tree-ssa/pr94718-3.c: New test. PR tree-optimization/94718 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94718-4.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94718-4.c new file mode 100644 index 0000000..8b9c109 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94718-4.c @@ -0,0 +1,61 @@ +/* PR tree-optimization/94718 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-ipa-icf -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times "= \[xy]_\[0-9]+\\\(D\\\) \\^ \[xy]_\[0-9]+\\\(D\\\);" 8 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\[0-9]+ < 0;" 8 "optimized" } } */ + +int +f1 (int x, int y) +{ + return (x < 0) != (y < 0); +} + +int +f2 (int x, int y) +{ + return (x >= 0) != (y >= 0); +} + +int +f3 (int x, int y) +{ + return (x < 0) == (y >= 0); +} + +int +f4 (int x, int y) +{ + return (x >= 0) == (y < 0); +} + +int +f5 (int x, int y) +{ + int s = (x < 0); + int t = (y < 0); + return s != t; +} + +int +f6 (int x, int y) +{ + int s = (x >= 0); + int t = (y >= 0); + return s != t; +} + +int +f7 (int x, int y) +{ + int s = (x < 0); + int t = (y >= 0); + return s == t; +} + +int +f8 (int x, int y) +{ + int s = (x >= 0); + int t = (y < 0); + return s == t; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94718-5.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94718-5.c new file mode 100644 index 0000000..4bd3732 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94718-5.c @@ -0,0 +1,61 @@ +/* PR tree-optimization/94718 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-ipa-icf -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times "= \[xy]_\[0-9]+\\\(D\\\) \\^ \[xy]_\[0-9]+\\\(D\\\);" 8 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\[0-9]+ >= 0;" 8 "optimized" } } */ + +int +f1 (int x, int y) +{ + return (x < 0) == (y < 0); +} + +int +f2 (int x, int y) +{ + return (x >= 0) == (y >= 0); +} + +int +f3 (int x, int y) +{ + return (x < 0) != (y >= 0); +} + +int +f4 (int x, int y) +{ + return (x >= 0) != (y < 0); +} + +int +f5 (int x, int y) +{ + int s = (x < 0); + int t = (y < 0); + return s == t; +} + +int +f6 (int x, int y) +{ + int s = (x >= 0); + int t = (y >= 0); + return s == t; +} + +int +f7 (int x, int y) +{ + int s = (x < 0); + int t = (y >= 0); + return s != t; +} + +int +f8 (int x, int y) +{ + int s = (x >= 0); + int t = (y < 0); + return s != t; +} |