From 98610dc5b630a8ee7f39ed48d45e58fb044dbec1 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 6 Dec 2018 11:45:47 +0100 Subject: [PATCH] re PR tree-optimization/85726 (div C1 to div C2 match.pd suboptimization) 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 | 6 ++++++ gcc/generic-match-head.c | 9 +++++++++ gcc/gimple-match-head.c | 24 +++++++++++++++++++++++ gcc/match.pd | 14 +++++++------ gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.dg/tree-ssa/pr85726-1.c | 19 ++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr85726-2.c | 15 ++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr85726-3.c | 15 ++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr85726-4.c | 15 ++++++++++++++ 9 files changed, 117 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr85726-1.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr85726-2.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr85726-3.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr85726-4.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b60efcf4821..a40d99e1ada 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2018-12-06 Jakub Jelinek + 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. diff --git a/gcc/generic-match-head.c b/gcc/generic-match-head.c index f7b6b1f23c5..0165bd09112 100644 --- a/gcc/generic-match-head.c +++ b/gcc/generic-match-head.c @@ -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; +} diff --git a/gcc/gimple-match-head.c b/gcc/gimple-match-head.c index d6c60ab34db..374232bb696 100644 --- a/gcc/gimple-match-head.c +++ b/gcc/gimple-match-head.c @@ -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; +} diff --git a/gcc/match.pd b/gcc/match.pd index 698d27fe777..fbb4d6fa6a0 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -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. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bc5bf6720ec..13d2e25a096 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,11 @@ 2018-12-06 Jakub Jelinek + 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 index 00000000000..25c3e4913ea --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr85726-1.c @@ -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 index 00000000000..834a6899790 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr85726-2.c @@ -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 index 00000000000..7241fb06e1a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr85726-3.c @@ -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 index 00000000000..f57cf3a6900 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr85726-4.c @@ -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; +} -- 2.30.2