]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
match.pd: factor MSB OR-cascade out of clz_table_index
authorPhilipp Tomsich <philipp.tomsich@vrull.eu>
Fri, 8 May 2026 17:22:04 +0000 (19:22 +0200)
committerPhilipp Tomsich <philipp.tomsich@vrull.eu>
Fri, 3 Jul 2026 21:04:38 +0000 (23:04 +0200)
Factor the 5- and 6-stage MSB OR-cascade -- which sets every bit from 0
to the input's MSB -- into two helper match patterns msb_or_cascade_32
and msb_or_cascade_64, and rewrite the 32-bit and 64-bit clz_table_index
patterns as one-liners over them.  The helpers retain the
integral/unsigned/precision and shift-constant checks, so this is a
no-functional-change refactor.

It prepares a follow-up that recognises a CLZ idiom isolating the MSB
before the DeBruijn multiply, which reuses msb_or_cascade_64 directly.

gcc/ChangeLog:

* match.pd (msb_or_cascade_32, msb_or_cascade_64): New match
helpers.
(clz_table_index): Rewrite the 32-bit and 64-bit forms to use
the cascade helpers.

gcc/match.pd

index a4a1ac94860ac7cde1d494548ac67b92f1dc2495..7983211a793094b8db7910b62af19f5f5110898d 100644 (file)
@@ -11973,21 +11973,20 @@ and,
 (match (ctz_table_index @1 @2 @3)
   (rshift (mult (bit_and:c (negate @1) @1) INTEGER_CST@2) INTEGER_CST@3))
 
-/* Match count leading zeros for simplify_count_zeroes in forwprop.
-   One canonical form is 31 - array[idx] where IDX is computed from X
-   by first setting all bits from the topmost set bits down via a
-   series of shifts and ors to X' and then computing (X' * C) >> SHIFT.  */
-(match (clz_table_index @1 @2 @3)
-  (rshift (mult
-   (bit_ior (rshift
-     (bit_ior@d (rshift
-       (bit_ior@c (rshift
-         (bit_ior@b (rshift
-          (bit_ior@a (rshift @1 INTEGER_CST@c1) @1)
-          INTEGER_CST@c2) @a)
-        INTEGER_CST@c4) @b)
-       INTEGER_CST@c8) @c)
-     INTEGER_CST@c16) @d) INTEGER_CST@2) INTEGER_CST@3)
+/* Helpers for clz_table_index and its variants: match the 5- or
+   6-stage MSB OR-cascade that drives a DeBruijn CLZ lookup.  Given a
+   value @1, the cascade sets every bit from 0 to the MSB of @1,
+   producing 2^(k+1) - 1 where k is the MSB position.  */
+(match (msb_or_cascade_32 @1)
+  (bit_ior (rshift
+    (bit_ior@d (rshift
+      (bit_ior@c (rshift
+       (bit_ior@b (rshift
+         (bit_ior@a (rshift @1 INTEGER_CST@c1) @1)
+         INTEGER_CST@c2) @a)
+       INTEGER_CST@c4) @b)
+      INTEGER_CST@c8) @c)
+    INTEGER_CST@c16) @d)
   (if (INTEGRAL_TYPE_P (type)
        && TYPE_UNSIGNED (type)
        && TYPE_PRECISION (type) == 32
@@ -11996,19 +11995,19 @@ and,
        && compare_tree_int (@c4, 4) == 0
        && compare_tree_int (@c8, 8) == 0
        && compare_tree_int (@c16, 16) == 0)))
-(match (clz_table_index @1 @2 @3)
-  (rshift (mult
-   (bit_ior (rshift
-     (bit_ior@e (rshift
-       (bit_ior@d (rshift
-         (bit_ior@c (rshift
-           (bit_ior@b (rshift
-            (bit_ior@a (rshift @1 INTEGER_CST@c1) @1)
-            INTEGER_CST@c2) @a)
-          INTEGER_CST@c4) @b)
-         INTEGER_CST@c8) @c)
-       INTEGER_CST@c16) @d)
-     INTEGER_CST@c32) @e) INTEGER_CST@2) INTEGER_CST@3)
+
+(match (msb_or_cascade_64 @1)
+  (bit_ior (rshift
+    (bit_ior@e (rshift
+      (bit_ior@d (rshift
+       (bit_ior@c (rshift
+         (bit_ior@b (rshift
+           (bit_ior@a (rshift @1 INTEGER_CST@c1) @1)
+           INTEGER_CST@c2) @a)
+         INTEGER_CST@c4) @b)
+       INTEGER_CST@c8) @c)
+      INTEGER_CST@c16) @d)
+    INTEGER_CST@c32) @e)
   (if (INTEGRAL_TYPE_P (type)
        && TYPE_UNSIGNED (type)
        && TYPE_PRECISION (type) == 64
@@ -12019,6 +12018,15 @@ and,
        && compare_tree_int (@c16, 16) == 0
        && compare_tree_int (@c32, 32) == 0)))
 
+/* Match count leading zeros for simplify_count_zeroes in forwprop.
+   One canonical form is 31 - array[idx] where IDX is computed from X
+   by first setting all bits from the topmost set bits down via a
+   series of shifts and ors to X' and then computing (X' * C) >> SHIFT.  */
+(match (clz_table_index @1 @2 @3)
+  (rshift (mult (msb_or_cascade_32 @1) INTEGER_CST@2) INTEGER_CST@3))
+(match (clz_table_index @1 @2 @3)
+  (rshift (mult (msb_or_cascade_64 @1) INTEGER_CST@2) INTEGER_CST@3))
+
 /* Floatint point/integer comparison and integer->integer
    or floating point -> float point conversion.  */
 (match (cond_expr_convert_p @0 @2 @3 @6)