RTL is able to do this optimization but doing it earlier on gimple
can promote further optimizations during tree-opt.

Boostrapped and regression tested in x86_64 and aarch64.

        PR tree-optimization/126523

gcc/ChangeLog:

        * match.pd(`(SIGNED (bit_not (UNSIGNED signed_var)))`): New
        pattern.

gcc/testsuite/ChangeLog:

        * gcc.dg/tree-ssa/pr126523.c: New test.
---
 gcc/match.pd                             | 14 +++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/pr126523.c | 26 ++++++++++++++++++++++++
 2 files changed, 40 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr126523.c

diff --git a/gcc/match.pd b/gcc/match.pd
index e59c11d5d13..2b3713e7360 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -13279,6 +13279,20 @@ and,
       && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@0)))
   (convert @0)))
 
+/* PR126523: (SIGNED (~(UNSIGNED signed_var))) -> ~signed_var.  */
+(simplify
+ (convert (bit_not (convert@1 @0)))
+ (if (INTEGRAL_TYPE_P (type)
+      && !TYPE_UNSIGNED (type)
+      && TREE_TYPE (@0) == type
+      && TYPE_UNSIGNED (TREE_TYPE (@1))
+      /* Check single_use since we're getting rid of @1.  */
+      && single_use (@1)
+      /* The unsigned convert cannot have less bits
+        than the signed result.  */
+      && TYPE_PRECISION (TREE_TYPE (@1)) >= TYPE_PRECISION (type))
+  (bit_not @0)))
+
 /* Optimize
    c1 = VEC_PERM_EXPR (a, a, mask)
    c2 = VEC_PERM_EXPR (b, b, mask)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr126523.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr126523.c
new file mode 100644
index 00000000000..a8199c0b7ee
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr126523.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+typedef int si;
+typedef unsigned ui;
+
+si f(si a)
+{
+    ui t = a;
+    t = ~t;
+    si a1 = t;
+    return a1;
+}
+
+si f1(si a)
+{
+    return ~a;
+}
+
+/* If everything went as planned g()
+   will reduce to 'return 1'.  */
+int g(si a)
+{
+    return f(a) + f1(a) == (si)(2*(~a));
+}
+/* { dg-final { scan-tree-dump-times " return 1;" 1 "optimized" } } */
-- 
2.43.0

Reply via email to