[My first attempt at submitting a patch for gcc, so please forgive me if I'm not following the right protocol.]
Sometimes rounding a variable to the next even integer is written x += x & 1. This usually means using an extra register (and hence at least an extra mov instruction) compared to the equivalent x = (x + 1) & ~1. The first pattern below tries to do this transformation. While playing with various ways of rounding down, I noticed that gcc already optimizes all of x-(x&3), x^(x&3) and x&~(x&3) to simply x&~3. In fact, x&~(x&y) is rewritten as x&~y. However, the dual of this is not handled, so I included the second pattern below. I've tested the below in the sense that gcc compiles and that trivial test cases get compiled as expected. Rasmus diff --git gcc/match.pd gcc/match.pd index 81c4ee6..04a0bc4 100644 --- gcc/match.pd +++ gcc/match.pd @@ -262,6 +262,16 @@ along with GCC; see the file COPYING3. If not see (abs tree_expr_nonnegative_p@0) @0) +/* x + (x & 1) -> (x + 1) & ~1 */ +(simplify + (plus @0 (bit_and @0 integer_onep@1)) + (bit_and (plus @0 @1) (bit_not @1))) + +/* x | ~(x | y) -> x | ~y */ +(simplify + (bit_ior @0 (bit_not (bit_ior @0 @1))) + (bit_ior @0 (bit_not @1))) + /* Try to fold (type) X op CST -> (type) (X op ((type-x) CST)) when profitable.