[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:
parent
46dc26fdfb
commit
d9fa599dc7
12
gcc/match.pd
12
gcc/match.pd
|
@ -8026,3 +8026,15 @@ and,
|
||||||
(match (bitwise_induction_p @0 @2 @3)
|
(match (bitwise_induction_p @0 @2 @3)
|
||||||
(bit_not
|
(bit_not
|
||||||
(nop_convert1? (bit_xor@0 (convert2? (lshift integer_onep@1 @2)) @3))))
|
(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))))))
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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" } } */
|
Loading…
Reference in New Issue