On 11/29/2016 03:16 AM, Richard Biener wrote:
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.
Agreed. I managed to convince myself that for a signed type with the
sign bit on that we'd generate incorrect code. But that was from a
quick review of the pattern.
Jeff