[gcc r17-2815] MATCH: Simplify min of clz/ctz to clz/ctz of bitwise or [PR123311]
Eikansh Gupta via Gcc-cvs <[email protected]> Thu, 30 Jul 2026 08:06:49 +0000 (GMT)
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:1743c12e3512bff3c9688dff7bba5b2ac43cd9d5 commit r17-2815-g1743c12e3512bff3c9688dff7bba5b2ac43cd9d5 Author: Eikansh Gupta <[email protected]> Date: Tue May 19 12:20:54 2026 +0530 MATCH: Simplify min of clz/ctz to clz/ctz of bitwise or [PR123311] This adds match.pd simplifications for min(clz(x), clz(y)) and min(ctz(x), ctz(y)) to clz(x | y) and ctz(x | y). Bootstrapped and tested on aarch64-linux-gnu and x86_64-linux-gnu. PR tree-optimization/123311 gcc/ChangeLog: * match.pd (min(clz(x), clz(y)) -> clz(x | y)): New pattern. (min(ctz(x), ctz(y)) -> ctz(x | y)): Likewise. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/pr123311-1.c: New test. * gcc.dg/tree-ssa/pr123311-2.c: New test. Signed-off-by: Eikansh Gupta <[email protected]> Diff: --- gcc/match.pd | 17 +++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr123311-1.c | 21 +++++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr123311-2.c | 25 +++++++++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/gcc/match.pd b/gcc/match.pd index 3658a355c40c..782cfe7dc557 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -10389,6 +10389,23 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (!HONOR_SIGN_DEPENDENT_ROUNDING (type) && single_use (@3)) (IFN_COND_FMA @4 @0 @1 @2 (negate @5))))) +/* min (clz (x), clz (y)) -> clz (x | y) and + min (ctz (x), ctz (y)) -> ctz (x | y). */ +(for func (CLZ CTZ) + (simplify + (min (func:s @0) (func:s @1)) + (if (types_match (@0, @1) + && (!sanitize_flags_p (SANITIZE_BUILTIN) + || (cfun && (cfun->curr_properties & PROP_ssa) != 0))) + (func (bit_ior @0 @1))))) +(for func (IFN_CLZ IFN_CTZ) + (simplify + (min (func:s @0 INTEGER_CST@2) (func:s @1 @2)) + (if (types_match (@0, @1) + && wi::geu_p (wi::to_wide (@2), + TYPE_PRECISION (TREE_TYPE (@0)))) + (func (bit_ior @0 @1) @2)))) + /* CLZ simplifications. */ (for clz (CLZ) (for op (eq ne) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr123311-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr123311-1.c new file mode 100644 index 000000000000..59622e5a3535 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr123311-1.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +#define min(x, y) ((x) < (y) ? (x) : (y)) + +int +f1 (unsigned int x, unsigned int y) +{ + return min (__builtin_ctz (x), __builtin_ctz (y)); +} + +int +f2 (unsigned int x, unsigned int y) +{ + return min (__builtin_clz (x), __builtin_clz (y)); +} + +/* { dg-final { scan-tree-dump-times " \\\| " 2 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "__builtin_ctz|\\.CTZ" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "__builtin_clz|\\.CLZ" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-not "MIN_EXPR" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr123311-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr123311-2.c new file mode 100644 index 000000000000..0f55c32a1bbd --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr123311-2.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-additional-options "-mbmi -mlzcnt" { target i?86-*-* x86_64-*-* } } */ +/* { dg-require-effective-target clz } */ +/* { dg-require-effective-target ctz } */ + +#define W (__SIZEOF_INT__ * __CHAR_BIT__) +#define min(x, y) ((x) < (y) ? (x) : (y)) + +int +f1 (unsigned int x, unsigned int y) +{ + return min (__builtin_ctzg (x, W), __builtin_ctzg (y, W)); +} + +int +f2 (unsigned int x, unsigned int y) +{ + return min (__builtin_clzg (x, W), __builtin_clzg (y, W)); +} + +/* { dg-final { scan-tree-dump-times " \\\| " 2 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "__builtin_ctz|\\.CTZ" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "__builtin_clz|\\.CLZ" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-not "MIN_EXPR" "optimized" } } */