[PATCH] match.pd: Add new bitwise arithmetic pattern [PR98304]

PR tree-optimization/98304

gcc:

	* match.pd (n - (((n > C1) ? n : C1) & -C2)): New simplification.

gcc/testsuite:

	* gcc.c-torture/execute/pr98304-2.c: New test.
	* gcc.dg/pr98304-1.c: New test.
This commit is contained in:
Sam Feifer 2022-07-09 12:08:01 -04:00 committed by Jeff Law
parent 46dc26fdfb
commit d9fa599dc7
3 changed files with 106 additions and 0 deletions

View File

@ -8026,3 +8026,15 @@ and,
(match (bitwise_induction_p @0 @2 @3)
(bit_not
(nop_convert1? (bit_xor@0 (convert2? (lshift integer_onep@1 @2)) @3))))
/* n - (((n > C1) ? n : C1) & -C2) -> n & C1 for unsigned case.
n - (((n > C1) ? n : C1) & -C2) -> (n <= C1) ? n : (n & C1) for signed case. */
(simplify
(minus @0 (bit_and (max @0 INTEGER_CST@1) INTEGER_CST@2))
(with { auto i = wi::neg (wi::to_wide (@2)); }
/* Check if -C2 is a power of 2 and C1 = -C2 - 1. */
(if (wi::popcount (i) == 1
&& (wi::to_wide (@1)) == (i - 1))
(if (TYPE_UNSIGNED (TREE_TYPE (@0)))
(bit_and @0 @1)
(cond (le @0 @1) @0 (bit_and @0 @1))))))

View File

@ -0,0 +1,37 @@
/* PR tree-optimization/98304 */
#include "../../gcc.dg/pr98304-1.c"
/* Runtime tests. */
int main() {
/* Signed tests. */
if (foo(-42) != -42
|| foo(0) != 0
|| foo(63) != 63
|| foo(64) != 0
|| foo(65) != 1
|| foo(99) != 35) {
__builtin_abort();
}
/* Unsigned tests. */
if (bar(42) != 42
|| bar(0) != 0
|| bar(63) != 63
|| bar(64) != 0
|| bar(65) != 1
|| bar(99) != 35) {
__builtin_abort();
}
/* Should not simplify. */
if (corge(13) != 13
|| thud(13) != 13
|| qux(13) != 13
|| quux(13) != 13) {
__builtin_abort();
}
return 0;
}

View File

@ -0,0 +1,57 @@
/* PR tree-optimization/98304 */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
/* Signed test function. */
__attribute__((noipa)) int foo(int n) {
return n - (((n > 63) ? n : 63) & -64);
}
/* Unsigned test function. */
__attribute__((noipa)) unsigned int bar(unsigned int n) {
return n - (((n > 63) ? n : 63) & -64);
}
/* Different power of 2. */
__attribute__((noipa)) int goo(int n) {
return n - (((n > 31) ? n : 31) & -32);
}
/* Commutative property (should be identical to foo) */
__attribute__((noipa)) int baz(int n) {
return n - (((64 > n) ? 63 : n) & -64);
}
/* < instead of >. */
__attribute__((noipa)) int fred(int n) {
return n - (((63 < n) ? n : 63) & -64);
}
/* Constant is not a power of 2 so should not simplify. */
__attribute__((noipa)) int qux(int n) {
return n - (((n > 62) ? n : 62) & -63);
}
/* Constant is not a power of 2 so should not simplify. */
__attribute__((noipa)) unsigned int quux(unsigned int n) {
return n - (((n > 62) ? n : 62) & -63);
}
/* Constant is a variable so should not simplify. */
__attribute__((noipa)) int waldo(int n, int x) {
return n - (((n > 63) ? n : 63) & x);
}
/* Difference between constants is not -1. */
__attribute__((noipa)) int corge(int n) {
return n - (((n > 1) ? n : 1) & -64);
}
/* Difference between constants is not -1. */
__attribute__((noipa)) unsigned int thud(unsigned int n)
{
return n - (((n > 1) ? n : 1) & -64);
}
/* { dg-final { scan-tree-dump-times " - " 5 "optimized" } } */
/* { dg-final { scan-tree-dump-times " <= " 4 "optimized" } } */