Commit 98610dc5 by Jakub Jelinek Committed by Jakub Jelinek

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
parent a126d361
2018-12-06 Jakub Jelinek <jakub@redhat.com> 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 PR fortran/88304
* tree-nested.c (convert_nonlocal_reference_stmt): Remove clobbers * tree-nested.c (convert_nonlocal_reference_stmt): Remove clobbers
for non-local automatic decls. for non-local automatic decls.
...@@ -77,3 +77,12 @@ canonicalize_math_after_vectorization_p () ...@@ -77,3 +77,12 @@ canonicalize_math_after_vectorization_p ()
{ {
return false; 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;
}
...@@ -1163,3 +1163,27 @@ optimize_pow_to_exp (tree arg0, tree arg1) ...@@ -1163,3 +1163,27 @@ optimize_pow_to_exp (tree arg0, tree arg1)
return false; return false;
return true; 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;
}
...@@ -312,17 +312,19 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) ...@@ -312,17 +312,19 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
and floor_div is trickier and combining round_div even more so. */ and floor_div is trickier and combining round_div even more so. */
(for div (trunc_div exact_div) (for div (trunc_div exact_div)
(simplify (simplify
(div (div @0 INTEGER_CST@1) INTEGER_CST@2) (div (div@3 @0 INTEGER_CST@1) INTEGER_CST@2)
(with { (with {
wi::overflow_type overflow; wi::overflow_type overflow;
wide_int mul = wi::mul (wi::to_wide (@1), wi::to_wide (@2), wide_int mul = wi::mul (wi::to_wide (@1), wi::to_wide (@2),
TYPE_SIGN (type), &overflow); TYPE_SIGN (type), &overflow);
} }
(if (!overflow) (if (div == EXACT_DIV_EXPR
(div @0 { wide_int_to_tree (type, mul); }) || optimize_successive_divisions_p (@2, @3))
(if (TYPE_UNSIGNED (type) (if (!overflow)
|| mul != wi::min_value (TYPE_PRECISION (type), SIGNED)) (div @0 { wide_int_to_tree (type, mul); })
{ build_zero_cst (type); }))))) (if (TYPE_UNSIGNED (type)
|| mul != wi::min_value (TYPE_PRECISION (type), SIGNED))
{ build_zero_cst (type); }))))))
/* Combine successive multiplications. Similar to above, but handling /* Combine successive multiplications. Similar to above, but handling
overflow is different. */ overflow is different. */
......
2018-12-06 Jakub Jelinek <jakub@redhat.com> 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 PR fortran/88304
* gfortran.fortran-torture/compile/pr88304.f90: New test. * gfortran.fortran-torture/compile/pr88304.f90: New test.
......
/* 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;
}
/* 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;
}
/* 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;
}
/* 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment