From: Philipp Tomsich Date: Fri, 8 May 2026 17:22:04 +0000 (+0200) Subject: match.pd: factor MSB OR-cascade out of clz_table_index X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d5044b85d3bd3ed0b8ddae3ea186eef747b1ef2d;p=thirdparty%2Fgcc.git match.pd: factor MSB OR-cascade out of clz_table_index 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. --- diff --git a/gcc/match.pd b/gcc/match.pd index a4a1ac94860..7983211a793 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -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)