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).
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.c: New test.
Signed-off-by: Eikansh Gupta <[email protected]>
---
gcc/match.pd | 17 ++++++++++++
gcc/testsuite/gcc.dg/tree-ssa/pr123311.c | 34 ++++++++++++++++++++++++
2 files changed, 51 insertions(+)
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr123311.c
diff --git a/gcc/match.pd b/gcc/match.pd
index 8c410c2f3b3..5f489ecbefd 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -10169,6 +10169,23 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(if (!HONOR_SIGN_DEPENDENT_ROUNDING (type) && single_use (@3))
(IFN_COND_FMA @4 @0 @1 @2 @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)) - 1))
+ (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.c
b/gcc/testsuite/gcc.dg/tree-ssa/pr123311.c
new file mode 100644
index 00000000000..d9d61bfced8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr123311.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+#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_ctz (x), __builtin_ctz (y));
+}
+
+int
+f2 (unsigned int x, unsigned int y)
+{
+ return min (__builtin_clz (x), __builtin_clz (y));
+}
+
+int
+f3 (unsigned int x, unsigned int y)
+{
+ return min (__builtin_ctzg (x, W), __builtin_ctzg (y, W));
+}
+
+int
+f4 (unsigned int x, unsigned int y)
+{
+ return min (__builtin_clzg (x, W), __builtin_clzg (y, W));
+}
+
+/* { dg-final { scan-tree-dump-times " \\\| " 4 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_ctz|\\.CTZ" 2 "optimized" } }
*/
+/* { dg-final { scan-tree-dump-times "__builtin_clz|\\.CLZ" 2 "optimized" } }
*/
+/* { dg-final { scan-tree-dump-not "MIN_EXPR" "optimized" } } */
--
2.34.1