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.
This commit is contained in:
parent
a1a0dc4548
commit
553c657206
5 changed files with 264 additions and 0 deletions
29
gcc/match.pd
29
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)
|
||||
|
|
42
gcc/testsuite/gcc.dg/tree-ssa/pr94882-1.c
Normal file
42
gcc/testsuite/gcc.dg/tree-ssa/pr94882-1.c
Normal file
|
@ -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;
|
||||
}
|
78
gcc/testsuite/gcc.dg/tree-ssa/pr94882-2.c
Normal file
78
gcc/testsuite/gcc.dg/tree-ssa/pr94882-2.c
Normal file
|
@ -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;
|
||||
}
|
79
gcc/testsuite/gcc.dg/tree-ssa/pr94882-3.c
Normal file
79
gcc/testsuite/gcc.dg/tree-ssa/pr94882-3.c
Normal file
|
@ -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);
|
||||
}
|
36
gcc/testsuite/gcc.dg/tree-ssa/pr94882.c
Normal file
36
gcc/testsuite/gcc.dg/tree-ssa/pr94882.c
Normal file
|
@ -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;
|
||||
}
|
Loading…
Add table
Reference in a new issue