Fix PR94880: Failure to recognize andn pattern

Pattern "(x | y) - y" can be optimized to simple "(x & ~y)" andn
pattern.

Bootstrapped and tested on aarch64-none-linux-gnu.

gcc/ChangeLog:

	PR tree-optimization/94880
	* match.pd (A | B) - B -> (A & ~B): New simplification.

gcc/testsuite/ChangeLog:

	PR tree-optimization/94880
	* gcc.dg/tree-ssa/pr94880.c: New Test.
This commit is contained in:
Przemyslaw Wirkus 2020-06-19 16:48:55 +01:00 committed by Alex Coplan
parent 6d8b2ee568
commit e0bfe01671
2 changed files with 34 additions and 0 deletions

View File

@ -1109,6 +1109,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
&& !TYPE_SATURATING (type))
(bit_ior @0 @1)))
/* (x | y) - y -> (x & ~y) */
(simplify
(minus (bit_ior:cs @0 @1) @1)
(bit_and @0 (bit_not @1)))
/* (x | y) - (x ^ y) -> x & y */
(simplify
(minus (bit_ior @0 @1) (bit_xor @0 @1))

View File

@ -0,0 +1,29 @@
/* PR tree-optimization/94786 */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
/* { dg-final { scan-tree-dump-times "= ~\[xy\]_" 4 "optimized" } } */
/* { dg-final { scan-tree-dump-times " & \[xy\]_" 4 "optimized" } } */
unsigned
foo_u(unsigned x, unsigned y)
{
return (x | y) - y;
}
int
foo_i(int x, int y)
{
return (x | y) - y;
}
unsigned long long
foo_ull(unsigned long long x, unsigned long long y)
{
return (x | y) - y;
}
long long
foo_ll(long long x, long long y)
{
return (x | y) - y;
}