re PR tree-optimization/85726 (div C1 to div C2 match.pd suboptimization)
authorJakub Jelinek <jakub@redhat.com>
Thu, 6 Dec 2018 10:45:47 +0000 (11:45 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 6 Dec 2018 10:45:47 +0000 (11:45 +0100)
PR tree-optimization/85726
* generic-match-head.c (optimize_successive_divisions_p): New function.
* gimple-match-head.c (optimize_successive_divisions_p): Likewise.
* match.pd: Don't combine successive divisions if they aren't exact
and optimize_successive_divisions_p is false.

* gcc.dg/tree-ssa/pr85726-1.c: New test.
* gcc.dg/tree-ssa/pr85726-2.c: New test.
* gcc.dg/tree-ssa/pr85726-3.c: New test.
* gcc.dg/tree-ssa/pr85726-4.c: New test.

From-SVN: r266848

gcc/ChangeLog
gcc/generic-match-head.c
gcc/gimple-match-head.c
gcc/match.pd
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr85726-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/pr85726-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/pr85726-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/pr85726-4.c [new file with mode: 0644]

index b60efcf4821fa54aa13a759b9dae0f9fee0af254..a40d99e1ada95f656fbbc721a7ce023287c2524b 100644 (file)
@@ -1,5 +1,11 @@
 2018-12-06  Jakub Jelinek  <jakub@redhat.com>
 
+       PR tree-optimization/85726
+       * generic-match-head.c (optimize_successive_divisions_p): New function.
+       * gimple-match-head.c (optimize_successive_divisions_p): Likewise.
+       * match.pd: Don't combine successive divisions if they aren't exact
+       and optimize_successive_divisions_p is false.
+
        PR fortran/88304
        * tree-nested.c (convert_nonlocal_reference_stmt): Remove clobbers
        for non-local automatic decls.
index f7b6b1f23c58d92fda6f6b9f36da7b35778e028f..0165bd09112c8393c72528c6566cc257d8742017 100644 (file)
@@ -77,3 +77,12 @@ canonicalize_math_after_vectorization_p ()
 {
   return false;
 }
+
+/* Return true if successive divisions can be optimized.
+   Defer to GIMPLE opts.  */
+
+static inline bool
+optimize_successive_divisions_p (tree, tree)
+{
+  return false;
+}
index d6c60ab34db6eafcc9e2b8a5d077a8734f5bf5ba..374232bb696fb0cef2d09adbcc8a81acf7ac4ace 100644 (file)
@@ -1163,3 +1163,27 @@ optimize_pow_to_exp (tree arg0, tree arg1)
     return false;
   return true;
 }
+
+/* Return true if a division INNER_DIV / DIVISOR where INNER_DIV
+   is another division can be optimized.  Don't optimize if INNER_DIV
+   is used in a TRUNC_MOD_EXPR with DIVISOR as second operand.  */
+
+static bool
+optimize_successive_divisions_p (tree divisor, tree inner_div)
+{
+  if (!gimple_in_ssa_p (cfun))
+    return false;
+
+  imm_use_iterator imm_iter;
+  use_operand_p use_p;
+  FOR_EACH_IMM_USE_FAST (use_p, imm_iter, inner_div)
+    {
+      gimple *use_stmt = USE_STMT (use_p);
+      if (!is_gimple_assign (use_stmt)
+         || gimple_assign_rhs_code (use_stmt) != TRUNC_MOD_EXPR
+         || !operand_equal_p (gimple_assign_rhs2 (use_stmt), divisor, 0))
+       continue;
+      return false;
+    }
+  return true;
+}
index 698d27fe7777ef36a2b7b973548c0a1b0ebecea9..fbb4d6fa6a02af0ca603c354f34c2ec3ebef7b4e 100644 (file)
@@ -312,17 +312,19 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
    and floor_div is trickier and combining round_div even more so.  */
 (for div (trunc_div exact_div)
  (simplify
-  (div (div @0 INTEGER_CST@1) INTEGER_CST@2)
+  (div (div@3 @0 INTEGER_CST@1) INTEGER_CST@2)
   (with {
     wi::overflow_type overflow;
     wide_int mul = wi::mul (wi::to_wide (@1), wi::to_wide (@2),
                            TYPE_SIGN (type), &overflow);
    }
-   (if (!overflow)
-    (div @0 { wide_int_to_tree (type, mul); })
-    (if (TYPE_UNSIGNED (type)
-        || mul != wi::min_value (TYPE_PRECISION (type), SIGNED))
-     { build_zero_cst (type); })))))
+   (if (div == EXACT_DIV_EXPR
+       || optimize_successive_divisions_p (@2, @3))
+    (if (!overflow)
+     (div @0 { wide_int_to_tree (type, mul); })
+     (if (TYPE_UNSIGNED (type)
+         || mul != wi::min_value (TYPE_PRECISION (type), SIGNED))
+      { build_zero_cst (type); }))))))
 
 /* Combine successive multiplications.  Similar to above, but handling
    overflow is different.  */
index bc5bf6720ecc51d028300a6ef48ee511b210a992..13d2e25a096563f8e4bcbb25f3de410505afe911 100644 (file)
@@ -1,5 +1,11 @@
 2018-12-06  Jakub Jelinek  <jakub@redhat.com>
 
+       PR tree-optimization/85726
+       * gcc.dg/tree-ssa/pr85726-1.c: New test.
+       * gcc.dg/tree-ssa/pr85726-2.c: New test.
+       * gcc.dg/tree-ssa/pr85726-3.c: New test.
+       * gcc.dg/tree-ssa/pr85726-4.c: New test.
+
        PR fortran/88304
        * gfortran.fortran-torture/compile/pr88304.f90: New test.
 
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr85726-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr85726-1.c
new file mode 100644 (file)
index 0000000..25c3e49
--- /dev/null
@@ -0,0 +1,19 @@
+/* PR tree-optimization/85726 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump " / 16;" "optimized" } } */
+/* { dg-final { scan-tree-dump " / 3;" "optimized" } } */
+/* { dg-final { scan-tree-dump " % 3;" "optimized" } } */
+/* { dg-final { scan-tree-dump-not " / 48;" "optimized" } } */
+
+int ww, vv;
+
+int
+foo (int y)
+{
+  int z = y / 16;
+  int w = z / 3;
+  int v = z % 3;
+  ww = w;
+  return v;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr85726-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr85726-2.c
new file mode 100644 (file)
index 0000000..834a689
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR tree-optimization/85726 */
+/* { dg-do compile { target int32 } } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump " / 3145728;" "optimized" } } */
+/* { dg-final { scan-tree-dump "y = 0;" "optimized" } } */
+
+int x, y;
+
+void
+foo (int n)
+{
+  int c = 3 << 20;
+  x = n / c;
+  y = x / c;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr85726-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr85726-3.c
new file mode 100644 (file)
index 0000000..7241fb0
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR tree-optimization/85726 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times " / 3;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " / 15;" 1 "optimized" } } */
+
+int x, y, z;
+
+void
+foo (int n)
+{
+  x = n / 3;
+  y = x / 5;
+  z = n / 15;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr85726-4.c b/gcc/testsuite/gcc.dg/tree-ssa/pr85726-4.c
new file mode 100644 (file)
index 0000000..f57cf3a
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR tree-optimization/85726 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times " / 4;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " / 16;" 1 "optimized" } } */
+
+int x, y, z;
+
+void
+foo (int n)
+{
+  x = n / 4;
+  y = x / 4;
+  z = y * 16 | 15;
+}