On Mon, Nov 28, 2016 at 7:41 PM, Jeff Law <l...@redhat.com> wrote: > On 11/28/2016 06:10 AM, Paolo Bonzini wrote: >> >> >> >> 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. > > But are we absolutely sure it'll be in canonical form every time?
No, of course not (though it would be a bug). If the pattern generates wrong code when the non-canonical form is met that would be bad, if it merely does not optimize (or optimize non-optimally) then that's not too bad. > Is there > a pattern in in match.pd which turns an (x & SIGN_BIT) tests into canonical > form? > > >> >> (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? > > Shouldn't be necessary if we're working on unsigned types. May be necessary > on signed types unless we're 100% sure sign bit tests will be canonicalized. Instead of the bit_and better put a if() condition around this. Richard. > jeff