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? 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.

jeff

Reply via email to