https://gcc.gnu.org/g:262163238006aa39eff5ebd8283ec7254161269a

commit 262163238006aa39eff5ebd8283ec7254161269a
Author: Roger Sayle <ro...@nextmovesoftware.com>
Date:   Sat Jul 27 15:16:19 2024 +0100

    Fold ctz(-x) and ctz(abs(x)) as ctz(x) in match.pd.
    
    The subject line pretty much says it all; the count-trailing-zeros function
    of -X and abs(X) produce the same result as count-trailing-zeros of X.
    This transformation eliminates a negation which may potentially overflow
    with an equivalent expression that doesn't [much like the analogous
    abs(-X) simplification in match.pd].
    
    I'd noticed this -X equivalence, which isn't mentioned in Hacker's Delight,
    investigating whether ranger's non_zero_bits can help determine whether
    an integer variable may be converted to a floating point type exactly
    (without raising FE_INEXACT), but it turns out this observation isn't
    novel, as (disappointingly) LLVM already performs this same folding.
    
    2024-07-27  Roger Sayle  <ro...@nextmovesoftware.com>
                Andrew Pinski  <quic_apin...@quicinc.com>
    
    gcc/ChangeLog
            * match.pd (ctz (-X) => ctz (X)): New simplification.
            (ctz (abs (X)) => ctz (X)): Likewise.
    
    gcc/testsuite/ChangeLog
            * gcc.dg/fold-ctz-1.c: New test case.
            * gcc.dg/fold-ctz-2.c: Likewise.

Diff:
---
 gcc/match.pd                      | 6 ++++++
 gcc/testsuite/gcc.dg/fold-ctz-1.c | 9 +++++++++
 gcc/testsuite/gcc.dg/fold-ctz-2.c | 9 +++++++++
 3 files changed, 24 insertions(+)

diff --git a/gcc/match.pd b/gcc/match.pd
index b2e7d61790df..1c8601229e3d 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -9102,6 +9102,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 
 /* CTZ simplifications.  */
 (for ctz (CTZ)
+ /* ctz (-X) => ctz (X).  ctz (abs (X)) => ctz (X).  */
+ (for op (negate abs)
+  (simplify
+   (ctz (nop_convert?@0 (op @1)))
+    (with { tree t = TREE_TYPE (@0); }
+     (ctz (convert:t @1)))))
  (for op (ge gt le lt)
       cmp (eq eq ne ne)
   (simplify
diff --git a/gcc/testsuite/gcc.dg/fold-ctz-1.c 
b/gcc/testsuite/gcc.dg/fold-ctz-1.c
new file mode 100644
index 000000000000..dcc444cbbb6b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-ctz-1.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int foo(int x)
+{
+  return __builtin_ctz (-x);
+}
+
+/* { dg-final { scan-tree-dump-not "-x_" "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/fold-ctz-2.c 
b/gcc/testsuite/gcc.dg/fold-ctz-2.c
new file mode 100644
index 000000000000..c685698f31e5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-ctz-2.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int foo(int x)
+{
+  return __builtin_ctz (__builtin_abs (x));
+}
+
+/* { dg-final { scan-tree-dump-not "ABS_EXPR" "optimized"} } */

Reply via email to