On 27/11/2016 00:28, Marc Glisse wrote: > On Sat, 26 Nov 2016, Paolo Bonzini wrote: > >> --- match.pd (revision 242742) >> +++ match.pd (working copy) >> @@ -2554,6 +2554,19 @@ >> (cmp (bit_and@2 @0 integer_pow2p@1) @1) >> (icmp @2 { build_zero_cst (TREE_TYPE (@0)); }))) >> >> +/* If we have (A & C) != 0 ? D : 0 where C and D are powers of 2, >> + convert this into a shift of (A & C). */ >> +(simplify >> + (cond >> + (ne (bit_and@2 @0 integer_pow2p@1) integer_zerop) >> + integer_pow2p@3 integer_zerop) >> + (with { >> + int shift = wi::exact_log2 (@3) - wi::exact_log2 (@1); >> + } >> + (if (shift > 0) >> + (lshift (convert @2) { build_int_cst (integer_type_node, shift); }) >> + (convert (rshift @2 { build_int_cst (integer_type_node, -shift); >> }))))) > > What happens if @1 is the sign bit, in a signed type? Do we get an > arithmetic shift right?
It shouldn't happen because the canonical form of a sign bit test is A < 0 (that's the pattern immediately after). However I can add an "if" if preferred, or change the pattern to do the AND after the shift. (bit_and (if (shift > 0) (lshift (convert @0) { build_int_cst (integer_type_node, shift); }) (convert (rshift @0 { build_int_cst (integer_type_node, -shift); }))) @3) What do you think? Paolo