MATCH: Move (x | y) & (~x ^ y)
over to use bitwise_inverted_equal_p
This moves the match pattern `(x | y) & (~x ^ y)` over to use bitwise_inverted_equal_p. This now also allows to optmize comparisons and also catches the missed `(~x | y) & (x ^ y)` transformation into `~x & y`. OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions. gcc/ChangeLog: PR tree-optimization/111147 * match.pd (`(x | y) & (~x ^ y)`) Use bitwise_inverted_equal_p instead of matching bit_not. gcc/testsuite/ChangeLog: PR tree-optimization/111147 * gcc.dg/tree-ssa/cmpbit-4.c: New test.
This commit is contained in:
parent
97aafa9cbb
commit
7c04da768c
2 changed files with 52 additions and 2 deletions
|
@ -1616,8 +1616,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
|
|||
|
||||
/* (x | y) & (~x ^ y) -> x & y */
|
||||
(simplify
|
||||
(bit_and:c (bit_ior:c @0 @1) (bit_xor:c @1 (bit_not @0)))
|
||||
(bit_and @0 @1))
|
||||
(bit_and:c (bit_ior:c @0 @1) (bit_xor:c @1 @2))
|
||||
(with { bool wascmp; }
|
||||
(if (bitwise_inverted_equal_p (@0, @2, wascmp)
|
||||
&& (!wascmp || element_precision (type) == 1))
|
||||
(bit_and @0 @1))))
|
||||
|
||||
/* (~x | y) & (x | ~y) -> ~(x ^ y) */
|
||||
(simplify
|
||||
|
|
47
gcc/testsuite/gcc.dg/tree-ssa/cmpbit-4.c
Normal file
47
gcc/testsuite/gcc.dg/tree-ssa/cmpbit-4.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
|
||||
|
||||
int g(int x, int y)
|
||||
{
|
||||
int xp = ~x;
|
||||
return (x | y) & (xp ^ y); // x & y
|
||||
}
|
||||
int g0(int x, int y)
|
||||
{
|
||||
int xp = ~x;
|
||||
return (xp | y) & (x ^ y); // ~x & y
|
||||
}
|
||||
|
||||
_Bool gb(_Bool x, _Bool y)
|
||||
{
|
||||
_Bool xp = !x;
|
||||
return (x | y) & (xp ^ y); // x & y
|
||||
}
|
||||
_Bool gb0(_Bool x, _Bool y)
|
||||
{
|
||||
_Bool xp = !x;
|
||||
return (xp | y) & (x ^ y); // !x & y
|
||||
}
|
||||
|
||||
|
||||
_Bool gbi(int a, int b)
|
||||
{
|
||||
_Bool x = a < 2;
|
||||
_Bool y = b < 3;
|
||||
_Bool xp = !x;
|
||||
return (x | y) & (xp ^ y); // x & y
|
||||
}
|
||||
_Bool gbi0(int a, int b)
|
||||
{
|
||||
_Bool x = a < 2;
|
||||
_Bool y = b < 3;
|
||||
_Bool xp = !x;
|
||||
return (xp | y) & (x ^ y); // !x & y
|
||||
}
|
||||
|
||||
/* All of these should be optimized to `x & y` or `~x & y` */
|
||||
/* { dg-final { scan-tree-dump-times "le_expr, " 3 "optimized" } } */
|
||||
/* { dg-final { scan-tree-dump-times "gt_expr, " 1 "optimized" } } */
|
||||
/* { dg-final { scan-tree-dump-not "bit_xor_expr, " "optimized" } } */
|
||||
/* { dg-final { scan-tree-dump-times "bit_and_expr, " 6 "optimized" } } */
|
||||
/* { dg-final { scan-tree-dump-times "bit_not_expr, " 2 "optimized" } } */
|
Loading…
Add table
Reference in a new issue