gcc.dg/20150120-1.c: New test Rounding an integer to the next even integer is sometimes written x += x & 1. The equivalent x = (x+1)&~1 usually uses one less register, and in practical cases only the new value of x will be used (making it unlikely that the subexpression x&1 has any uses).
Signed-off-by: Rasmus Villemoes <r...@rasmusvillemoes.dk> --- gcc/match.pd | 6 +++++ gcc/testsuite/gcc.dg/20150120-1.c | 51 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/20150120-1.c diff --git gcc/match.pd gcc/match.pd index 81c4ee6..ecefcfb 100644 --- gcc/match.pd +++ gcc/match.pd @@ -255,6 +255,12 @@ along with GCC; see the file COPYING3. If not see (bitop @0 @0) (non_lvalue @0))) +/* x + (x & 1) -> (x + 1) & ~1 */ +(simplify + (plus:c @0 (bit_and@2 @0 integer_onep@1)) + (if (TREE_CODE (@2) != SSA_NAME || has_single_use (@2)) + (bit_and (plus @0 @1) (bit_not @1)))) + (simplify (abs (negate @0)) (abs @0)) diff --git gcc/testsuite/gcc.dg/20150120-1.c gcc/testsuite/gcc.dg/20150120-1.c new file mode 100644 index 0000000..18906c4 --- /dev/null +++ gcc/testsuite/gcc.dg/20150120-1.c @@ -0,0 +1,51 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-original" } */ + +/* x + (x & 1) -> (x + 1) & ~1 */ +int +fn1 (int x) +{ + return x + (x & 1); +} +int +fn2 (int x) +{ + return (x & 1) + x; +} +int +fn3 (int x) +{ + return x + (1 & x); +} +int +fn4 (int x) +{ + return (1 & x) + x; +} +unsigned int +fn5 (unsigned int x) +{ + return x + (x & 1); +} +unsigned int +fn6 (unsigned int x) +{ + return (x & 1) + x; +} +unsigned int +fn7 (unsigned int x) +{ + return x + (x % 2); +} +unsigned int +fn8 (unsigned int x) +{ + return (x % 2) + x; +} +unsigned int +fn9 (unsigned int x) +{ + return (1LL & x) + x; +} + +/* { dg-final { scan-tree-dump-times "x \\+ 1" 9 "original" } } */ -- 2.1.3