Commit 5a892248 by Richard Biener Committed by Richard Biener

re PR tree-optimization/57343 (wrong code on x86_64-linux at -Os and above)

2013-05-27  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/57343
	* tree-ssa-loop-niter.c (number_of_iterations_ne_max): Do not
	use multiple_of_p if not TYPE_OVERFLOW_UNDEFINED.
	(number_of_iterations_cond): Do not build the folded tree.

	* gcc.dg/torture/pr57343.c: New testcase.

From-SVN: r199357
parent d1de852b
2013-05-27 Richard Biener <rguenther@suse.de> 2013-05-27 Richard Biener <rguenther@suse.de>
PR tree-optimization/57343
* tree-ssa-loop-niter.c (number_of_iterations_ne_max): Do not
use multiple_of_p if not TYPE_OVERFLOW_UNDEFINED.
(number_of_iterations_cond): Do not build the folded tree.
2013-05-27 Richard Biener <rguenther@suse.de>
Revert Revert
PR middle-end/57381 PR middle-end/57381
* fold-const.c (operand_equal_p): Compare FIELD_DECLs with * fold-const.c (operand_equal_p): Compare FIELD_DECLs with
......
2013-05-27 Richard Biener <rguenther@suse.de> 2013-05-27 Richard Biener <rguenther@suse.de>
PR tree-optimization/57343
* gcc.dg/torture/pr57343.c: New testcase.
2013-05-27 Richard Biener <rguenther@suse.de>
PR tree-optimization/57417 PR tree-optimization/57417
* gcc.dg/torture/pr57417.c: New testcase. * gcc.dg/torture/pr57417.c: New testcase.
......
/* { dg-do run } */
int c = 0;
int
main ()
{
int i, f = 1;
for (i = 0; i < 5; i++)
{
--c;
unsigned char h = c * 100;
if (h == 0)
{
f = 0;
break;
}
}
if (f != 1)
__builtin_abort ();
return 0;
}
...@@ -552,10 +552,18 @@ number_of_iterations_ne_max (mpz_t bnd, bool no_overflow, tree c, tree s, ...@@ -552,10 +552,18 @@ number_of_iterations_ne_max (mpz_t bnd, bool no_overflow, tree c, tree s,
{ {
double_int max; double_int max;
mpz_t d; mpz_t d;
tree type = TREE_TYPE (c);
bool bnds_u_valid = ((no_overflow && exit_must_be_taken) bool bnds_u_valid = ((no_overflow && exit_must_be_taken)
|| mpz_sgn (bnds->below) >= 0); || mpz_sgn (bnds->below) >= 0);
if (multiple_of_p (TREE_TYPE (c), c, s)) if (integer_onep (s)
|| (TREE_CODE (c) == INTEGER_CST
&& TREE_CODE (s) == INTEGER_CST
&& tree_to_double_int (c).mod (tree_to_double_int (s),
TYPE_UNSIGNED (type),
EXACT_DIV_EXPR).is_zero ())
|| (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (c))
&& multiple_of_p (type, c, s)))
{ {
/* If C is an exact multiple of S, then its value will be reached before /* If C is an exact multiple of S, then its value will be reached before
the induction variable overflows (unless the loop is exited in some the induction variable overflows (unless the loop is exited in some
...@@ -572,16 +580,15 @@ number_of_iterations_ne_max (mpz_t bnd, bool no_overflow, tree c, tree s, ...@@ -572,16 +580,15 @@ number_of_iterations_ne_max (mpz_t bnd, bool no_overflow, tree c, tree s,
the whole # of iterations analysis will fail). */ the whole # of iterations analysis will fail). */
if (!no_overflow) if (!no_overflow)
{ {
max = double_int::mask (TYPE_PRECISION (TREE_TYPE (c)) max = double_int::mask (TYPE_PRECISION (type)
- tree_low_cst (num_ending_zeros (s), 1)); - tree_low_cst (num_ending_zeros (s), 1));
mpz_set_double_int (bnd, max, true); mpz_set_double_int (bnd, max, true);
return; return;
} }
/* Now we know that the induction variable does not overflow, so the loop /* Now we know that the induction variable does not overflow, so the loop
iterates at most (range of type / S) times. */ iterates at most (range of type / S) times. */
mpz_set_double_int (bnd, double_int::mask (TYPE_PRECISION (TREE_TYPE (c))), mpz_set_double_int (bnd, double_int::mask (TYPE_PRECISION (type)), true);
true);
/* If the induction variable is guaranteed to reach the value of C before /* If the induction variable is guaranteed to reach the value of C before
overflow, ... */ overflow, ... */
...@@ -1311,7 +1318,8 @@ number_of_iterations_cond (struct loop *loop, ...@@ -1311,7 +1318,8 @@ number_of_iterations_cond (struct loop *loop,
} }
/* If the loop exits immediately, there is nothing to do. */ /* If the loop exits immediately, there is nothing to do. */
if (integer_zerop (fold_build2 (code, boolean_type_node, iv0->base, iv1->base))) tree tem = fold_binary (code, boolean_type_node, iv0->base, iv1->base);
if (tem && integer_zerop (tem))
{ {
niter->niter = build_int_cst (unsigned_type_for (type), 0); niter->niter = build_int_cst (unsigned_type_for (type), 0);
niter->max = double_int_zero; niter->max = double_int_zero;
......
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