diff options
author | Jeff Law <law@redhat.com> | 2020-07-01 14:44:07 -0600 |
---|---|---|
committer | Jeff Law <law@redhat.com> | 2020-07-01 14:49:30 -0600 |
commit | 553c6572061f6f9ef92514e8f13de95d509ad614 (patch) | |
tree | 08ad79c49a6c99ca517942d2e5f6c45bf4fc6370 | |
parent | a1a0dc4548979f8a340a7ea71624a52a20e1e0b3 (diff) | |
download | gcc-553c6572061f6f9ef92514e8f13de95d509ad614.zip gcc-553c6572061f6f9ef92514e8f13de95d509ad614.tar.gz gcc-553c6572061f6f9ef92514e8f13de95d509ad614.tar.bz2 |
match.pd: (x & y) - (x | y) - 1 -> ~(x ^ y) simplification [PR94882]
gcc/
PR tree-optimization/94882
* match.pd (x & y) - (x | y) - 1 -> ~(x ^ y): New simplification.
gcc/testsuite/
PR tree-optimization/94882
* gcc.dg/tree-ssa/pr94882.c: New test.
* gcc.dg/tree-ssa/pr94882-1.c: New test.
* gcc.dg/tree-ssa/pr94882-2.c: New test.
* gcc.dg/tree-ssa/pr94882-3.c: New test.
-rw-r--r-- | gcc/match.pd | 29 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr94882-1.c | 42 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr94882-2.c | 78 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr94882-3.c | 79 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr94882.c | 36 |
5 files changed, 264 insertions, 0 deletions
diff --git a/gcc/match.pd b/gcc/match.pd index 43f3d7a..c6ae7a7 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1144,6 +1144,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 0000000..976b8e5 --- /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 0000000..7f533b6 --- /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 0000000..979162f --- /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 0000000..e7a55308 --- /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; +} |