On December 12, 2020 9:10:41 AM GMT+01:00, Jakub Jelinek <ja...@redhat.com> 
wrote:
>Hi!
>
>This patch adds the ~(X - Y) -> ~X + Y simplification requested
>in the PR (plus also ~(X + C) -> ~X + (-C) for constants C that can
>be safely negated.
>
>The first two simplify blocks is what has been requested in the PR
>and that makes the first testcase pass.
>Unfortunately, that change also breaks the second testcase, because
>while the same expressions appearing in the same stmt and split
>across multiple stmts has been folded (not really) before, with
>this optimization fold-const.c optimizes ~X + Y further into
>(Y - X) - 1 in fold_binary_loc associate: code, but we have nothing
>like that in GIMPLE and so end up with different expressions.
>
>The last simplify is an attempt to deal with just this case,
>had to rule out there the Y == -1U case, because then we
>reached infinite recursion as ~X + -1U was canonicalized by
>the pattern into (-1U - X) + -1U but there is a canonicalization
>-1 - A -> ~A that turns it back.  Furthermore, had to make it
>#if GIMPLE only, because it otherwise resulted in infinite recursion
>when interacting with the associate: optimization.
>The end result is that we pass all 3 testcases and thus canonizalize
>the 3 possible forms of writing the same thing.
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok. 

Thanks, 
Richard. 

>2020-12-12  Jakub Jelinek  <ja...@redhat.com>
>
>       PR tree-optimization/96685
>       * match.pd (~(X - Y) -> ~X + Y): New optimization.
>       (~X + Y -> (Y - X) - 1): Likewise.
>
>       * gcc.dg/tree-ssa/pr96685-1.c: New test.
>       * gcc.dg/tree-ssa/pr96685-2.c: New test.
>       * gcc.dg/tree-ssa/pr96685-3.c: New test.
>
>--- gcc/match.pd.jj    2020-12-11 16:41:45.797787831 +0100
>+++ gcc/match.pd       2020-12-11 23:12:45.769291586 +0100
>@@ -1074,6 +1074,34 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>  (bit_not (plus:c (bit_not @0) @1))
>  (minus @0 @1))
> 
>+/* ~(X - Y) -> ~X + Y.  */
>+(simplify
>+ (bit_not (minus:s @0 @1))
>+ (plus (bit_not @0) @1))
>+(simplify
>+ (bit_not (plus:s @0 INTEGER_CST@1))
>+ (if ((INTEGRAL_TYPE_P (type)
>+       && TYPE_UNSIGNED (type))
>+      || (!TYPE_OVERFLOW_SANITIZED (type)
>+        && may_negate_without_overflow_p (@1)))
>+  (plus (bit_not @0) { const_unop (NEGATE_EXPR, type, @1); })))
>+
>+#if GIMPLE
>+/* ~X + Y -> (Y - X) - 1.  */
>+(simplify
>+ (plus:c (bit_not @0) @1)
>+  (if (ANY_INTEGRAL_TYPE_P (type)
>+       && TYPE_OVERFLOW_WRAPS (type)
>+       /* -1 - X is folded to ~X, so we'd recurse endlessly.  */
>+       && !integer_all_onesp (@1))
>+   (plus (minus @1 @0) { build_minus_one_cst (type); })
>+   (if (INTEGRAL_TYPE_P (type)
>+      && TREE_CODE (@1) == INTEGER_CST
>+      && wi::to_wide (@1) != wi::min_value (TYPE_PRECISION (type),
>+                                            SIGNED))
>+    (minus (plus @1 { build_minus_one_cst (type); }) @0))))
>+#endif
>+
> /* x + (x & 1) -> (x + 1) & ~1 */
> (simplify
>  (plus:c @0 (bit_and:s @0 integer_onep@1))
>--- gcc/testsuite/gcc.dg/tree-ssa/pr96685-1.c.jj       2020-12-11
>16:42:03.975584838 +0100
>+++ gcc/testsuite/gcc.dg/tree-ssa/pr96685-1.c  2020-12-11
>16:42:03.975584838 +0100
>@@ -0,0 +1,52 @@
>+/* PR tree-optimization/96685 */
>+/* { dg-do compile } */
>+/* { dg-options "-O2 -fdump-tree-optimized" } */
>+/* { dg-final { scan-tree-dump-times "return 1;" 6 "optimized" } } */
>+
>+unsigned
>+f1 (unsigned x, unsigned y)
>+{
>+  unsigned a = ~(x - y);
>+  unsigned b = ~x + y;
>+  return a == b;
>+}
>+
>+unsigned
>+f2 (unsigned x)
>+{
>+  unsigned a = ~(x + -124U);
>+  unsigned b = ~x + 124U;
>+  return a == b;
>+}
>+
>+unsigned
>+f3 (unsigned x)
>+{
>+  unsigned a = ~(x + 124U);
>+  unsigned b = ~x + -124U;
>+  return a == b;
>+}
>+
>+int
>+f4 (int x, int y)
>+{
>+  int a = ~(x - y);
>+  int b = ~x + y;
>+  return a == b;
>+}
>+
>+int
>+f5 (int x)
>+{
>+  int a = ~(x + -124);
>+  int b = ~x + 124;
>+  return a == b;
>+}
>+
>+int
>+f6 (int x)
>+{
>+  int a = ~(x + 124);
>+  int b = ~x + -124;
>+  return a == b;
>+}
>--- gcc/testsuite/gcc.dg/tree-ssa/pr96685-2.c.jj       2020-12-11
>16:42:03.975584838 +0100
>+++ gcc/testsuite/gcc.dg/tree-ssa/pr96685-2.c  2020-12-11
>16:42:03.975584838 +0100
>@@ -0,0 +1,40 @@
>+/* PR tree-optimization/96685 */
>+/* { dg-do compile } */
>+/* { dg-options "-O2 -fdump-tree-optimized" } */
>+/* { dg-final { scan-tree-dump-times "return 1;" 4 "optimized" } } */
>+
>+int
>+f1 (unsigned x, unsigned y)
>+{
>+  unsigned int r1 = (x - y);
>+  r1 = ~r1;
>+  unsigned int r2 = ~(x - y);
>+  return r1 == r2;
>+}
>+
>+int
>+f2 (unsigned x, unsigned y)
>+{
>+  unsigned int r1 = (x - 23);
>+  r1 = ~r1;
>+  unsigned int r2 = ~(x - 23);
>+  return r1 == r2;
>+}
>+
>+int
>+f3 (int x, int y)
>+{
>+  int r1 = (x - y);
>+  r1 = ~r1;
>+  int r2 = ~(x - y);
>+  return r1 == r2;
>+}
>+
>+int
>+f4 (int x, int y)
>+{
>+  int r1 = (x - 23);
>+  r1 = ~r1;
>+  int r2 = ~(x - 23);
>+  return r1 == r2;
>+}
>--- gcc/testsuite/gcc.dg/tree-ssa/pr96685-3.c.jj       2020-12-11
>17:35:09.536123227 +0100
>+++ gcc/testsuite/gcc.dg/tree-ssa/pr96685-3.c  2020-12-11
>17:34:31.911543423 +0100
>@@ -0,0 +1,43 @@
>+/* PR tree-optimization/96685 */
>+/* { dg-do compile } */
>+/* { dg-options "-O2 -fdump-tree-optimized" } */
>+/* { dg-final { scan-tree-dump-times "return 1;" 4 "optimized" } } */
>+
>+int
>+f1 (unsigned x, unsigned y)
>+{
>+  unsigned int r1 = (x - y);
>+  r1 = ~r1;
>+  unsigned int r2 = (y - x);
>+  r2 = r2 - 1;
>+  return r1 == r2;
>+}
>+
>+int
>+f2 (unsigned x, unsigned y)
>+{
>+  unsigned int r1 = (x - 23);
>+  r1 = ~r1;
>+  unsigned int r2 = (23 - x);
>+  r2 = r2 - 1;
>+  return r1 == r2;
>+}
>+
>+int
>+f3 (int x, int y)
>+{
>+  int r1 = (x - 23);
>+  r1 = ~r1;
>+  int r2 = (23 - x);
>+  --r2;
>+  return r1 == r2;
>+}
>+
>+int
>+f4 (int x, int y)
>+{
>+  int r1 = (x - 23);
>+  r1 = ~r1;
>+  int r2 = (22 - x);
>+  return r1 == r2;
>+}
>
>       Jakub

Reply via email to